Search code examples
ruby-on-rails-3exceptionerror-handlingcustom-error-pages

Exception notifier - how to display own error pages?


I use exception_notification gem for handling an errors in an app. My ApplicationController looks like this:

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

In /config/enviroments/productions.rg in the end of the file I have:

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

when I get the error on the app - eg. Article.find(not-existing-ID), I'll get the standard error page (ERROR 500) from /public/500.html and not from the file specified in application controller... How is that possible? Past hours I tried to find the problem, but I still don't know the issue.


Solution

  • This works for me - from 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
    

    and

      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
    

    Note: I have my custom error pages in /app/views/pages. Called 500.html.haml and 404.html.haml

    I also have this in my routes.rb (note a hash after 'pages rather than a forward-slash):

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

    PS. See updated instructions here: http://ramblinglabs.com/blog/2012/01/rails-3-1-adding-custom-404-and-500-error-pages