Pregunta

I'm trying to write my 404 and 500 pages for my Rails 3.2.16 application. I've added to the application_controller.rb the following:

  def local_request?
    false
  end

  binding.pry
  unless  ActionController::Base.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

  def render_404(exception)
    logger.warning exception.backtrace.join("\n")
    @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.error 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

Though when I set my browser on http://localhost:3000/nonexistent, I see in the logs:

Started GET "/nonexistent" for 127.0.0.1 at 2014-04-22 13:45:12 +0100

ActionController::RoutingError (No route matches [GET] "/nonexistent"):
  actionpack (3.2.16) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (3.2.16) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  railties (3.2.16) lib/rails/rack/logger.rb:32:in `call_app'
  railties (3.2.16) lib/rails/rack/logger.rb:16:in `block in call'
  activesupport (3.2.16) lib/active_support/tagged_logging.rb:22:in `tagged'
  railties (3.2.16) lib/rails/rack/logger.rb:16:in `call'
  quiet_assets (1.0.2) lib/quiet_assets.rb:18:in `call_with_quiet_assets'
  actionpack (3.2.16) lib/action_dispatch/middleware/request_id.rb:22:in `call'
  rack (1.4.5) lib/rack/methodoverride.rb:21:in `call'
  rack (1.4.5) lib/rack/runtime.rb:17:in `call'
  activesupport (3.2.16) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  rack (1.4.5) lib/rack/lock.rb:15:in `call'
  actionpack (3.2.16) lib/action_dispatch/middleware/static.rb:63:in `call'
  railties (3.2.16) lib/rails/engine.rb:484:in `call'
  railties (3.2.16) lib/rails/application.rb:231:in `call'
  rack (1.4.5) lib/rack/content_length.rb:14:in `call'
  railties (3.2.16) lib/rails/rack/log_tailer.rb:17:in `call'
  rack (1.4.5) lib/rack/handler/webrick.rb:59:in `service'
  /Users/me/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/webrick/httpserver.rb:138:in `service'
  /Users/me/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/webrick/httpserver.rb:94:in `run'
  /Users/me/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/webrick/server.rb:295:in `block in start_thread'


  Rendered /Users/me/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-3.2.16/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (3.2ms)

It seems that the application_controller is not even executed so it doesn't load my custom 404 page.

I'm not sure how to solve this, and how to visualize the 404 and 500 pages on my development environment to make sure they look the way I want.

thanks,

¿Fue útil?

Solución 2

Here's a better way to do this:

#config/environments/production.rb
-> config/application.rb if you want on all environments
config.exceptions_app = ->(env) { ExceptionController.action(:show).call(env) }


#app/controllers/exception_controller.rb
class ExceptionController < ApplicationController
  respond_to :html, :xml, :json

    #Dependencies
    before_action :status

  #Layout
  layout :layout_status

  ####################
  #      Action      #
  ####################

    #Show
  def show
    respond_with status: @status
  end

  ####################
  #   Dependencies   #
  ####################

  protected

  #Info
  def status
    @exception  = env['action_dispatch.exception']
    @status     = ActionDispatch::ExceptionWrapper.new(env, @exception).status_code
    @response   = ActionDispatch::ExceptionWrapper.rescue_responses[@exception.class.name]
  end

  #Format
  def details
    @details ||= {}.tap do |h|
      I18n.with_options scope: [:exception, :show, @response], exception_name: @exception.class.name, exception_message: @exception.message do |i18n|
        h[:name]    = i18n.t "#{@exception.class.name.underscore}.title", default: i18n.t(:title, default: @exception.class.name)
        h[:message] = i18n.t "#{@exception.class.name.underscore}.description", default: i18n.t(:description, default: @exception.message)
      end
    end
  end
  helper_method :details

  ####################
  #      Layout      #
  ####################

  private

  #Layout
  def layout_status
    @status.to_s == "404" ? "application" : "error"
  end

end

#app/views/exception/show.html.haml
.box
%h1
    = details[:name]
%p
    = details[:message]

This works. Use @interpidd's answer if you want to run in dev

Otros consejos

In development.rb

Change

config.consider_all_requests_local = true

to

config.consider_all_requests_local = false

And restart your server. Your error pages will be displayed without all the debugging.

Better you start the server in production mode and verify it.

rails s -eproduction

then it will render the error page.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top