异常通知程序 - 如何显示自己的错误页面?

时间:2012-04-25 13:26:04

标签: ruby-on-rails-3 exception-handling error-handling custom-error-pages

我使用 exception_notification gem来处理应用中的错误。 我的 ApplicationController 如下所示:

unless Rails.application.config.consider_all_requests_local
    rescue_from Exception,
                :with => :render_error
    rescue_from ActiveRecord::RecordNotFound,
                :with => :render_not_found
    rescue_from ActionController::RoutingError,
                :with => :render_not_found
    rescue_from ActionController::UnknownController,
                :with => :render_not_found
    rescue_from ActionController::UnknownAction,
                :with => :render_not_found
  end

  def render_not_found(exception)
    ExceptionNotifier::Notifier
      .exception_notification(request.env, exception)
      .deliver
    render :template => "/errors/404.html.erb",
      :layout => 'errors.html.erb'
    return     
  end

  def render_error(exception)
    ExceptionNotifier::Notifier
      .exception_notification(request.env, exception)
      .deliver
    render :template => "/errors/500.html.erb",
           :layout => 'errors.html.erb'
    return
  end

在文件末尾的 /config/enviroments/productions.rg 中:

config.middleware.use ExceptionNotifier,
  :email_prefix => "[MY APP| Error Report] ",
  :sender_address => %{"MY APP" <err@my-app.com>},
  :exception_recipients => 'my_email@gmail.com'
end

我有两个问题:

  1. 当我在应用程序上收到错误时 - 例如Article.find(not-existing-ID),我将从/public/500.html获取标准错误页面(错误500)而不是应用程序控制器中指定的文件...这怎么可能?过去几个小时我试图找到问题,但我仍然不知道这个问题。

  2. 当我设置为url不存在的页面时,我得到错误号404 - 但在这种情况下,我没有收到有关此问题的电子邮件通知。有办法处理吗?第二件事,再次显示标准错误404页面,而不是来自/errors/404.html.erb的页面

  3. 有人可以给我一些建议,如何解决这些问题?

2 个答案:

答案 0 :(得分:3)

你的第一个问题:

这对我有用 - 来自application_controller.rb:

unless Rails.application.config.consider_all_requests_local
  rescue_from Exception, with: :render_500
  rescue_from ActionController::RoutingError, with: :render_404
  rescue_from ActionController::UnknownController, with: :render_404
  rescue_from ActionController::UnknownAction, with: :render_404
  rescue_from ActiveRecord::RecordNotFound, with: :render_404
end

  private
  def render_404(exception)
    ExceptionNotifier::Notifier.exception_notification(request.env, exception,
      :data => {:User => current_user.full_name, :Email => current_user.email, :UserID => current_user.id}).deliver
    @not_found_path = exception.message
    respond_to do |format|
      format.html { render template: 'pages/404', layout: 'layouts/application', status: 404 }
      format.all { render nothing: true, status: 404}
    end
  end
  def render_500(exception)
    ExceptionNotifier::Notifier.exception_notification(request.env, exception,
      :data => {:User => current_user.full_name, :Email => current_user.email, :UserID => current_user.id}).deliver
    @error = exception
    respond_to do |format|
      format.html { render template: 'pages/500', layout: 'layouts/application', status: 500 }
      format.all { render nothing: true, status: 500}
    end
  end

注意:我在/ app / views / pages中有自定义错误页面。称为500.html.haml和404.html.haml

我的routes.rb中也有这个(请注意'页面之后的哈希而不是正斜杠):

  unless Rails.application.config.consider_all_requests_local
    match '*not_found', to: 'pages#404'
  end

你的第二个问题: 我遇到与问题#2相同的问题(没有发送404邮件)。你找到了解决方案吗?

PS。请在此处查看更新的说明:http://ramblinglabs.com/blog/2012/01/rails-3-1-adding-custom-404-and-500-error-pages

答案 1 :(得分:0)

嗨这对我来说很有用!试试吧!

在application_controller.rb中,您可以添加以下代码:

 if Rails.env.production?
  unless Rails.application.config.consider_all_requests_local
    rescue_from Exception, with: :render_500
    rescue_from ActionController::RoutingError, with: :render_404
    rescue_from ActionController::UnknownController, with: :render_404
    rescue_from ActionController::UnknownAction, with: :render_404
    rescue_from ActiveRecord::RecordNotFound, with: :render_404
  end
 end

此代码检查您是否正在使用生产模式运行rails应用程序并捕获不同的救援错误。

在同一控制器“application_controller.rb”中添加以下代码:

def render_404(exception)
    @not_found_path = exception.message
    respond_to do |format|
      format.html { render template: 'errors/not_found', layout: 'layouts/application', status: 404 }
      format.all { render nothing: true, status: 404 }
    end
  end

  def render_500(exception)
    logger.info exception.backtrace.join("\n")
    respond_to do |format|
      format.html { render template: 'errors/internal_server_error', layout:      'layouts/application', status: 500 }
      format.all { render nothing: true, status: 500}
    end
  end

这些方法将指定您的应用捕获错误时要显示的页面, 然后创建一个名为:errors_controller.rb的控制器 然后在 app / view / errors 中 创建一个名为:

的文件
  • internal_server_error.html.erb 和
  • not_found.html.erb

并在 routes.rb 中 添加以下代码:

 match '/internal_server_error', :to => 'errors#internal_server_error'
 match '/not_found', :to => 'errors#not_found'