需求
rails的默认报错处理,是返回public/400.html
,public/500.html
的内容。
我们一般期望能够定制化它,根据用户登录或者状况返回一个动态渲染的页面。
我们一般希望能够定制:500服务器错误,400地址不存在。
解决方案
在你的app/controllers/application_controller.rb
的ApplicationController
里面用rescue_from
捕捉他们,并且只在生产环境这样做:
1
2
3
4
5
6
7
8
9
10
11
12
13
| class ApplicationController < ActionController::Base
...
unless Rails.application.config.consider_all_requests_local
rescue_from Exception, with: lambda { |exception|
render_error 500, exception
ExceptionNotifier::Notifier.exception_notification(request.env, exception).deliver
true
}
rescue_from ActionController::UnknownController, ActiveRecord::RecordNotFound, with: lambda { |exception|
render_error 404, exception
}
end
...
|
500报错需要能够通知管理员,上面的exception_notification
是我利用exception_notificationgem2.6版本中发送报错信息邮件的功能来做到这件事。
然后加上render_error
方法,用来渲染报错页面,你可以在这里做定制渲染:
1
2
3
4
5
6
| def render_error(status, exception)
respond_to do |format|
format.html { render template: "errors/error_#{status}", layout: 'layouts/application', status: status }
format.all { render nothing: true, status: status }
end
end
|
还是有一个问题,无法捕捉ActionController::RoutingError
和AbstractController::ActionNotFound
,需要在config/route.rb
里面最后捕捉:
1
2
3
| unless Rails.application.config.consider_all_requests_local
match '*not_found', to: 'errors#error_404'
end
|
加上errors_controller.rb
,里面:
1
2
3
4
5
| class ErrorsController < ApplicationController
def error_404
@not_found_path = params[:not_found]
render_error 404, nil
end
|
资源引用: