How can I display a custom error page with Ruby on Rails in any failure case?
I know that if an exception is raised in my main app, I can use the
exceptions_app configuration attribute to serve a dynamic error page.
However, if this error page is dynamic, it might also fail. In my case, I'm sharing some of the display logic with the main app, and it happened that that logic was the source of the exception, and rendering the error page raised it again. My end users then saw the Passenger error page, which is all purple and weird and frightening.
How can I reliably display a custom error page to my users, possibly with a static page fallback?
There is actually a whole series of configuration switches and redirection possibilities depending on your stack.
Here is a decision flow diagram showing all the possibilities. If you have a dynamic error page, you should really also add a static rendering of it in
public/500.html, and symlink it to some other file and reference that one in your web server (in the diagram, Apache’s
You cannot simply serve
public/<HTTP status code>.htmldirectly. Indeed, the web server would then consider
/<HTTP status code>requests as requests for the static page, and our errors controller would not trigger Rails routing anymore, preempting dynamic errors display.
You should set
false(more details), as well as disable your app runner (Passenger in the diagram) error page, otherwise you will leak exceptions content.
If you want to go to that level of detail, it is very important that you add integration tests on a user-hidden, voluntarily broken page, as you are disabling some debugging and failsafe features.
You could also be interested in the following references:
- Base tutorial for dynamic error pages in Rails.
- If you want to use your main app to display errors.
CustomErrorsHandleris a gem that automatically tries to use
<HTTP status code>.erbtemplates and falls back to static
public/<HTTP status code>.htmlpages.
- How to render a static version automatically by precompiling Rails Static 404 and 500 Pages.