rescue_from ActionController::RoutingError in Rails 4
In application_controller.rb
add the following:
# You want to get exceptions in development, but not in production. unless Rails.application.config.consider_all_requests_local rescue_from ActionController::RoutingError, with: -> { render_404 } end def render_404 respond_to do |format| format.html { render template: 'errors/not_found', status: 404 } format.all { render nothing: true, status: 404 } end end
I usually also rescue following exceptions, but that's up to you:
rescue_from ActionController::UnknownController, with: -> { render_404 }rescue_from ActiveRecord::RecordNotFound, with: -> { render_404 }
Create the errors controller:
class ErrorsController < ApplicationController def error_404 render 'errors/not_found' endend
Then in routes.rb
unless Rails.application.config.consider_all_requests_local # having created corresponding controller and action get '*path', to: 'errors#error_404', via: :all end
And the last thing is to create not_found.html.haml
(or whatever template engine you use) under /views/errors/
:
%span 404 %br Page Not Found
@Andrey Deineko, your solution seems to work only for the RoutingError
s raised manually inside a conrtoller. If I try it with the url my_app/not_existing_path
, I still get the standard error message.
I guess this is because the application doesn't even reach the controllers, since Rails raises the error before.
The trick that solved the problem for me was to add the following line at the end of the routes:
Rails.application.routes.draw do # existing paths match '*path' => 'errors#error_404', via: :allend
to catch all not predefined requests.
Then in the ErrorsController you can use respond_to
to serve html, json... requests:
class ErrorsController < ApplicationController def error_404 @requested_path = request.path repond_to do |format| format.html format.json { render json: {routing_error: @requested_path} } end endend
Copying favicon image in app/assets/images
worked for me.