rescue_from ActionController::RoutingError in Rails 4
Solution 1
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'
end
end
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
Solution 2
@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: :all
end
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
end
end
Solution 3
Copying favicon image in app/assets/images
worked for me.
Related videos on Youtube
Anna
Updated on July 09, 2022Comments
-
Anna almost 2 years
I've got the following error:
ActionController::RoutingError (No route matches [GET] "/images/favicon.ico")
I want to show error404 page for links that are not existing.
How can I achieve that?
-
depquid about 8 yearsThis doesn't work in Rails 4.2.5. I'm guessing that's because the exception is raised by ActionDispatch before any controller code is run.
-
Andrey Deineko about 8 years@depquid I wrote it in the times of Rails 4.0.x, but have just tested it with Rails 4.2.5 - I suppose you did not add route and did not create the
errors_controller.rb
:) If that is the case - please be sure to retract the downvote, unless you have more reasons to leave it -
depquid about 8 yearsSorry, I didn't set up the route correctly. But why have,
rescue_from ActionController::RoutingError, with: -> { render_404 }
if you're routing directly to the action? -
Afolabi Olaoluwa over 7 yearscould you explain
@requested_path = request.path
and its corresponding callformat.json { render json: {routing_error: @requested_path} }
? -
Misu over 7 yearsI've just used
@requested_path
in the template (error_404.html.haml). As for the json, if I'm sure I don't want a full page returned, for example by ajax, I can ask for json returned, and get the error message -
skplunkerin almost 6 years@misu this works perfect, your trick of adding this in the
config/routes.rb
file was the key -
skplunkerin almost 6 yearsIf you need to catch this before any Controller code is run (i.e. on the Routes level), see @misu's answer below for adding
match '*path' => 'errors#error_404', via: :all
. -
B Seven about 4 yearsHow can you get a
ActionController::RoutingError
when you have a path that matches everything (get '*path', to: 'errors#error_404', via: :all
) ?