网络寻租

Programmer, Gamer, Hacker

Rails定制报错页面

| Comments

需求

rails的默认报错处理,是返回public/400.htmlpublic/500.html的内容。 我们一般期望能够定制化它,根据用户登录或者状况返回一个动态渲染的页面。

我们一般希望能够定制:500服务器错误,400地址不存在。

解决方案

在你的app/controllers/application_controller.rbApplicationController里面用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::RoutingErrorAbstractController::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

资源引用:

Comments