在一个经典的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
错误重定向到admin_path或root_path(我尝试过其他路径以确保它不相关)
管理路径只显示一个仪表板:
class Admin::StaticController < Admin::AdminController
def dashboard
flash.keep
byebug
end
end
我试着添加flash。即使没有多重重定向,也要保持。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错误页面上阻止他们。然后我就可以实现内部错误处理(比如给应用程序的管理员/所有者发电子邮件)。
我试了一下,但没有成功。
为什么删除通知消息?为什么这种情况只会出现错误(我有很多重定向到通知,都很好)?
您不必创建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
设置异常通知宝石,
在Gemfile 中添加宝石
设置邮件:
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}
}
- 检查答案开头的应用程序控制器中的上述代码
为了使用这些路由,
match "/404", :to => "errors#not_found", :via => :all
match "/500", :to => "errors#internal_server_error", :via => :all
您必须在应用程序中设置异常处理程序。rb:
module RailsApp
class Application < Rails::Application
config.exceptions_app = self.routes