Rails 2 Custom Error Page
Contents |
so that error pages work for all types of requests, not justGET. Normally, 404 and 500 error pages are static rails error pages HTML files that live in the public directory of a
Rails Render 404 Page
Rails application. These are boring, minimally-styled pages that don’t get the same treatment as the rest rails exceptions_app of the app. This tutorial shows you how to move error pages into your Rails app as dynamic views that benefit from application styles, layouts,
Rails 4 Exceptions_app
and viewhelpers. tl;dr – jump to the Rails code and the Capistrano bonustip Why are dynamic error pages paticularly handy in Rails4? Starting with Rails 4, the production asset pipeline no longer generates filenames without cache-busters. This means that referencing /assets/application.css in your static public/404.html page won’t work in a Rails 4 rails 404 route app! The file will not exist in the production environment. The only way to reliably reference your application stylesheet is to use the stylesheet_link_taghelper. But error pages are static HTML pages; they can’t use helpers, right? If you want nice-looking error pages in Rails 4, here are youroptions: Option 1: No external styles. Don’t reference your application stylesheet at all. Instead, use simple, static error pages with the necessary minimal CSS copied and pasted into each HTML file. This is the solution that ships withRails. Works for simple apps that don’t need custom-branded errorpages. Option 2: Monkey patch. Use static error pages and point to /assets/application.css for styling. Then, monkey-patch Rails to restore the pre-Rails 4 behavior so that the asset pipeline generates non-cache-busted filenames in production. Make sure not to send far-future expires headers for thesefiles! Easiest option for migrating an existing app to Rails4. Option 3: Dynamic. Use dynamic view templates (ERB
Rails 3.2+ Starting with Rails 3.2, there is a nicer way
Rails 404 Page With Layout
to display custom error pages (i.e. "page not found") that
Rails Error Page Gem
does not interfere with ExceptionNotifier. (I'm not sure about Airbrake et al.) José Valim has posted rails 500 error this on his blog, here is a slightly more verbose rundown: Register your own app as the application responsible for showing error pages by adding https://mattbrictson.com/dynamic-rails-error-pages config.exceptions_app = self.routes to your config/application.rb. Add routes for the error pages, by appending this to your config/routes.rb: match '/404' => 'errors#not_found' match '/422' => 'errors#server_error' match '/500' => 'errors#server_error' Add an ErrorsController like this one: class ErrorsController < ApplicationController skip_before_action :verify_authenticity_token def not_found render :status => 404, :formats => https://makandracards.com/makandra/12807-custom-error-pages-in-rails-3-2+ [:html] end def server_error render :status => 500, :formats => [:html] end end Add the corresponding views. Add some tests, for example a cucumber feature: @allow-rescue Scenario: 404 page When I go to the path "/foobar" Then the page should be titled "Page not found" And I should see "We're sorry, but couldn't find the page you requested" And the response status should be "404" (Optional) In a request spec, you'll need to stub a few config variables (in the cached Rails environment config): # spec/requests/error_pages_spec.rb describe "Error pages" do def handle_errors env_config = Rails.application.env_config show_exceptions = env_config['action_dispatch.show_exceptions'] local_requests = env_config['action_dispatch.show_detailed_exceptions'] # Disables Rails built-in error reports, so our custom error application # can handle them and render it's own templates. This overrides the cached # setting in Rails.application.config.consider_all_requests_local env_config['action_dispatch.show_detailed_exceptions'] = false # Render exception templates instead of raising exceptions. # This is the cached setting for # Rails.application.config.action_dispatch.show_exception
1, 2015 Thibault Rails Rails' standard error handling is pretty weak (and ugly) out of the box: If you want to keep your app's branding consistent, this article https://samurails.com/jutsu/rails-jutsu/jutsu-12-custom-error-pages-in-rails-4/ will explain several ways to do it. -- How Rails Handles Exceptions Each time you send a request to a website, you'll be presented with a response belonging to one of the following http://railscasts.com/episodes/53-handling-exceptions-revised?view=comments categories: 10x (Informational) 20x (Success) 30x (Redirect) 40x (Not found) 50x (Server fault) If you've been developing with the web for any time, you'll undoubtedly be aware of at least the 404 and error page 500 error responses. These are part of the two response classes which constitute errors - 40x and 50x. The rest demonstrate successful requests. You can read about the different error types on Wikipedia. All web applications have to support these error messages. They are, after all, responses to requests. You can get good responses (10x / 20x / 30x) and erroneous responses (40x / 50x). The key rails error page for us is to make sure we catch the erroneous responses and direct them to our own error pages. The way Rails handles errors is through a middleware hook called exceptions_app. This captures any exceptions coming from Rails, allowing the middleware to create an appropriate response. In short, it's responsible for keeping your web server online if a problem does occur (as opposed to making it crash): This middleware [exceptions.app] rescues any exception returned by the application # and calls an exceptions app that will wrap it in a format for the end user. All the tutorials you find on how to create custom error pages hook into exceptions_app, allowing you to "divert" the user in the way you want. The "quality" of your error handling is dependent on what you do after you've caught the error. This is what we are to discuss: -- Catching errors with exceptions_app exceptions_app is a middleware hook for the ActiveDispatch::ShowExceptions middleware: Thus, any time you want to interject your own logic to the exception handling process, you have to override the exception_app middleware hook; pointing it to your own exception handling infrastructure. There are two ways to do this: Send
Handling Exceptions (revised) Apr 20, 2013 | 11 minutes | Controllers, Routing, Production, Rack By default, Rails will render a static error file when an exception occurs in production. Here you will learn how to fully customize this behavior and render dynamic error pages. Subscribe to Watch Episode Tweet Show NotesASCIIcast39 CommentsSimilar EpisodesNext Episode >< Previous Episode lazylester over 3 years ago In order to test the dynamic generation of error pages, you need to be in production environment, which is incompatible with running your entire test suite, normally in test environment. Similarly hacking the config.consider_all_requests_local parameter may is not viable except as a short-term hack to see dynamic error pages operating in dev or test environment. So I found it best to move the ErrorsController and associated views into a Rails engine... that way it can have a test suite of its own, running the tests in production environment. Bharat Ruparel over 3 years ago @laylester, could you please put out a sample/example on Github? Thanks. Bharat lazylester over 3 years ago @Bharat Ruparal https://github.com/lazylester/error_pages_engine Greg Silcox over 3 years ago This is certainly an area of my apps that needs some TLC. Thanks! Flambino over 3 years ago Nice episode, but it would be beneficial to add something like response.status = request.path[1..-1] to make the status code carry over (if anyone knows of a nicer way to do this, speak up). Otherwise, the error pages will all have a status of 200 OK since the error controller itself responded normally. Kamil Politowicz over 3 years ago Indeed - it may be not needed for HTML version, but definitely JSON API would benefit from having the right status code: render json: {error: @exception.message}, status: request.path[1..-1] Flambino over 3 years ago Yeah, web APIs are (or should be) sticklers for proper status codes, but any ol' HTML browser can infer a lot from the status code too. Whether or not to use the URL when auto-completing an address for the user, for instance. It's annoying to have the browser remember a URL for an error page, only because that page accidentally sent a 200 OK Tobias about 3 years ago I found a replacement for request.path[1..-1] posted by Jeroen Rosenberg: ruby status_code = ActionDispatch::ExceptionWrapper.new(env, @exception).status_code Jonathan Berglund over 3 years ago Has anyone found a good way to test this with RSpec? lazylester over