Reputation: 3284
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,
Upvotes: 0
Views: 2393
Reputation: 76774
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
Upvotes: 2
Reputation: 1714
Better you start the server in production mode and verify it.
rails s -eproduction
then it will render the error page.
Upvotes: 2
Reputation: 20878
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.
Upvotes: 3