【问题标题】:Custom error redirect, flash notice not working自定义错误重定向,闪烁通知不起作用
【发布时间】:2016-04-05 14:23:03
【问题描述】:

在一个经典的 Rails 应用程序中,我尝试使用自定义控制器处理错误,该控制器使用 Flash 消息重定向到 root_path。

路线:

match "/404", :to => "errors#not_found", :via => :all
match "/500", :to => "errors#internal_server_error", :via => :all

错误控制器:

class ErrorsController < Admin::AdminController
  def not_found
    redirect_to admin_path, notice: "Sorry, reccord not found"
  end

  def internal_server_error
    redirect_to root_path, notice: "Sorry, something went wrong"
  end
end

redirect_to admin_path 或 root_path 错误(我尝试了其他路径以确保它不相关)

管理路径只显示一个仪表板:

class Admin::StaticController < Admin::AdminController
  def dashboard
    flash.keep
    byebug
  end
end

即使没有多重重定向,我也尝试添加 flash.keep。 Byebug 停止该过程以帮助查看正在发生的事情,但此时闪烁通知显示为零。

日志(稍微清理一下):

Started GET something_not_possible_to_get
Completed 404 Not Found in 13ms (ActiveRecord: 2.3ms)
ActiveRecord::RecordNotFound
Processing by ErrorsController#not_found as HTML
Redirected to the_path
Started GET "/" (root_path)
ByeBug stopping here and notice is nil
continue just render the page as expected but without the notice

我想要实现的是将收到错误(404 或 500)的用户重定向到 root_path 或其他路径,让他们知道通知消息(flash)出了问题,但不会在经典 Rails 错误上阻止他们页。然后我就可以实现内部错误处理(例如,给应用程序的管理员/所有者发送电子邮件)。

我尝试了 keep.flash 没有成功。

为什么通知消息被丢弃?以及为什么仅在出现错误时才会发生这种情况(我有很多 redirect_to 通知都可以正常工作)?

【问题讨论】:

  • 根据你分享的日志,Redirected to root_path发生在用户遇到500错误,但在你的日志中却显示404错误。
  • 我尝试了 admin_path 和 root_path 甚至其他路径,但同样的事情发生了。实际上只有rescue方法会渲染通知。
  • 我正试图弄清楚这一点,因为我也想了解为什么它不通过重定向传递它,等待有人回答它。
  • 是的,我也是,这很奇怪,我只是想了解正在发生的事情或我错过了什么。我很确定这是一件小事(一如既往!)

标签: ruby-on-rails


【解决方案1】:

您不必创建 ErrorsController,而是可以捕获错误并执行您想要的任何操作。

您也可以使用exception_notification gem 将错误相关的邮件发送到配置的帐户。

在应用程序控制器中

class ApplicationController < ActionController::Base 
   rescue_from ActiveRecord::RecordNotFound, :with => :not_found
   rescue_from ActiveRecord::RecordInvalid, :with => :internal_server_error
   #some other errors that can be captured
   #rescue_from ActionController::MissingFile, :with => :render_404
   #rescue_from ActionController::RoutingError, :with => :render_404
   #rescue_from ActionView::TemplateError, :with => :render_500
   #rescue_from Errno::ENOENT, :with => :render_404
   #rescue_from Errno::EACCES, :with => :render_404

  def not_found
    notify(error)
    redirect_to admin_path, notice: "Sorry, reccord not found"
  end

  def internal_server_error
    notify(error)
    redirect_to root_path, notice: "Sorry, something went wrong"
  end

  def notify(exception)
   ExceptionNotifier::Notifier.exception_notification(request.env, exception,
    data: {message: 'An error occured'}).deliver
  end

end

设置 exception_notification gem

  1. 在 Gemfile 中添加 gem

  2. 设置邮件:

production.rb(在 development.rb 中实现相同的测试):

MyApp::Application.configure do
  #Action Mailer configuration to send emails
  config.action_mailer.delivery_method = :smtp

  config.action_mailer.smtp_settings = {
    :address => "smtp.gmail.com",
    :port => 587,
    :domain => "google.com",
    :user_name => "xyz@gmail.com",
    :password => "123",
    :authentication => "plain",
    :enable_starttls_auto => true 
  }
end

   MyApp::Application.config.middleware.use ExceptionNotification::Rack,
  :email => {
    :email_prefix => "[error in]",
    :sender_address => %{xyz@gmail.com},
    :exception_recipients => %w{xyz@gmail.com}
  }
  1. 在答案开头的Application Controller中检查上面的代码。

【讨论】:

  • 感谢您的回答,我将尝试您的救援示例,看看是否呈现通知。但是您的回答并未完全涵盖我要问的内容:为什么通知消失了?如果我想实现我的自定义错误控制器来处理这个问题怎么办?我会检查你提到的 gem 的代码,看看他们是如何实现这一点的。
  • 赞成:使用救援时,通知消息就在那里。我仍然想了解为什么自定义控制器没有得到相同的结果;)
  • 我猜在你的情况下它被重定向了两次,因为你没有捕获错误而是附加了你自己的方法。
  • 我也是这么想的,这也是我尝试使用为此目的设计的 flash.keep 的原因。但基本上它只是一个重定向到另一个控制器的控制器,并且通知被丢弃在某个地方。 Flash.keep 应该传递消息。
  • rescue_from ActionController::RoutingError is not working there很多关于这个的帖子你需要在路由中捕获所有“丢失的路由”并重定向到控制器。
【解决方案2】:

为了使用这些路线,

match "/404", :to => "errors#not_found", :via => :all
match "/500", :to => "errors#internal_server_error", :via => :all

您必须在 application.rb 中设置异常处理程序:

module RailsApp
  class Application < Rails::Application
    config.exceptions_app = self.routes

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    相关资源
    最近更新 更多