Rails bundles default 404 (file not found), 422 (unprocessable entity), and 500 (internal server error) pages into every newly generated application. While they get the job done, these pages are pretty bland, so in this post I’ll show you how to update them to suit the design of your application. As an example, here’s what the default 404 page looks like:
If you open any Rails application lacking custom error pages, you’ll find this 404 page in the file
public/404.html
. Therefore the easiest possible solution to creating custom error pages would be to simply edit each of these files as desired. Once updated, you can view them in your development environment by navigating directly to them (error pages aren’t shown by default in Rails’ development environment when an error occurs; more on this later in the post). For instance to see the custom 404 page you’d navigate to http://0.0.0.0:3000/404.html
.
While you could get away with directly modifying the 404.html
, 422.html
, and 500.html
pages, an alternative approach exists that provides more flexibility in terms of how these errors are handled and eliminates the need to potentially duplicate any layout markup that is otherwise automatically injected into your views. Even better, this alternative approach is accomplished in a few simple steps. Start by modifying your application.rb
file, adding the line
config.exceptions_app = self.routes
.
For instance here’s what the MyRailsAppconfig/application.rb
file looks like after adding this line:
module MyRailsApp
class Application < Rails::Application
config.exceptions_app = self.routes
end
end
This setting tells Rails to allow any exceptions to be handled by another application, which is in this case the application router.
Next, add the following three lines to the bottom of your
config/routes.rb
file:
match '/404', to: 'errors#file_not_found', via: :all
match '/422', to: 'errors#unprocessable', via: :all
match '/500', to: 'errors#internal_server_error', via: :all
The match
method is used to match a URL to one or more routes. It’s a bit more flexible than for instance the get
method because you can configure it to be triggered in conjunction with anymatching route and HTTP method as opposed to for instance just a route matching the get
method. You can pass specific HTTP methods into the via
option, however we want to match routes in conjunction with any HTTP method, and so I’ve passed all
into via
.Save these changes and next generate the
errors
controller and associated actions referenced in these newly created routes:$ rails g controller Errors file_not_found unprocessable internal_server_error
config/environments/development.rb
file:
config.consider_all_requests_local = false
After having added this line, restart your Rails server again, navigate to a non-existent URL, and you should see the file_not_found
default view!With the dynamic error handlers implemented, you have the convenience of allowing the default layout to be wrapped around the views, and can optionally implement more advanced handlers. For instance you can take advantage of various request methods to retrieve parts of the request (the requested page, parameters, etc) and build in logic that suggests possible desirable destinations!
No comments:
Post a Comment