For Rails 4.1 I like this answer, add an asset type better; however I have not tried it. On Rails 4.0.8, these three references helped me:
-
Dynamic error pages is the second reference in the question. This worked just fine for me.
-
Custom error pages may have cribbed from the first reference, or the other way around, but goes the extra mile by adding some information about testing with Capybara.
-
I did not do the Capybara testing because I didn’t want to change the test configuration; however, RSpec-Rails Request Specs clued me in to test these requests independently and see that they complete and return the correct content.
What follows is a nutshell description of what is taught by the three references:
-
Add the following setting to
config/environments/production.rb# Route exceptions to the application router vs. default config.exceptions_app = self.routes -
Edit the routing configuration,
config/routes.rbto direct the error pages to an errors controller# error pages %w( 404 422 500 503 ).each do |code| get code, :to => "errors#show", :code => code endwill route the 404, 422, 500, and 503 page requests to the
showaction of theerrorscontroller with a parametercodethat has the value of the status code. -
Create the controller,
app/controllers/errors_controller.rb. Here is the entire content:class ErrorsController < ApplicationController def show status_code = params[:code] || 500 flash.alert = "Status #{status_code}" render status_code.to_s, status: status_code end endMy preference was to set a status message on
flash.alert -
Create the pages themselves. I use
.erbHere isapp/views/errors/500.html.erb<p>Our apology. Your request caused an error.</p> <%= render 'product_description' %>So you see that you can render a partial. The page renders with all of the layout boilerplate from
app/views/layouts/application.html.erbor any other layout boilerplate that you have configured. That includes the<div id='alert'><%= alert %></div>that displays the status message from the flash. -
Tested with RSpec by adding a test file,
spec/requests/errors_request_spec.rb. Here is abbreviated content of that file that shows a test of the 500 status page:require 'rails_helper' RSpec.describe "errors", :type => :request do it "displays the 500 page" do get "/500" assert_select 'div#alert', 'Status 500' assert_select 'div[itemtype]' end endThe first assertion checks for the flash alert. The second assertion checks for the partial.