Rails 3.2 Custom Error Pages
Contents |
Share There is a lot of information out there about custom error pages in Rails 3.2 and how to use the built-in routing and the exceptions_app setting to get the basics
Rails Exceptions_app
working. Unfortunately, everything I found was missing a piece or two, so here's rails 4 exceptions_app my attempt at tying it all together. Beyond basic 404 and 500 pages If all you want is to route RecordNotFound actiondispatch::publicexceptions and routing errors to 404 and everything else to 500, it's pretty easy. Any of the posts in the references at the bottom can help you there. In my case, I also wanted a 401
Rails Custom Error Page
page for cases where users were attempting to access things they were not authorized to see. I wanted to be able to raise an exception anywhere in the code and have it result in responding to the user with a custom 401 page. 401 Unauthorized falls outside the default exceptions that Rails supports, so I had to create my own exception and tell Rails what to do when it occurred. First, define the exception: app/controllers/application_controller.rb class UnauthorizedException < Exception; end Next, tell Rails what to do when it sees it. config/application.rb config.action_dispatch.rescue_responses.merge!('ApplicationController::UnauthorizedException' => :unauthorized) The unauthorized symbol used corresponds to the 401 status code defined in Rack. There is a long list of status codes for Rack, and my best guess is that the symbol is the lowercase/underscore derivation of the string representation. In other words, a 402 Payment Required response can be referred to as :payment_required. So, define as many exceptions as you need and add them to the rescue_responses in your application.rb file. Routing to the ErrorsController and views Now that your exceptions are defined, you need to route them to your Errors controller and custom pages. config/application.rb config.exceptions_app = self.routes config/routes.rb match "/401" to: "errors#unauthorized" match "/404" to: "errors#not_found" match "/500" to: "errors#error" app/controllers/errors_controller.rb class ErrorsController < ApplicationController def unauthorized # Will render the app/views/errors/unauthorized.html.haml template end def not_found # Will render the app/views/errors/not_found.html.haml template end def error # Will render the app/views/errors/error.html.haml template end protected # The exception that resulted in this error action being called can be accessed from # the env. From there you can get a backtrace and/or message or whatever else is stored #
HTML files from the public root, is appropriately simple for 500 errors where your app may not be capable of rendering a dynamic page, but falls short for less grave errors, especially the common 404. I’ll often want to render a 404 using my application’s layout so as not to confuse users, include partials such as for http://agileleague.com/blog/rails-3-2-custom-error-pages-the-exceptions_app-and-testing-with-capybara/ a search form, and I recently worked on an internationalized app where I wanted to translate the 404 message. Rails will serve localized static pages (e.g. 404.en.html, 404.de.html), but I’d rather keep everything in my locale YAML files and render it with I18n.t('not_found'). The Old Ways In http://work.stevegrossi.com/2013/04/06/dynamic-error-pages-with-rails-3-2/ the past, I’ve handled this two ways. The simplest was to have a catch-all route at the bottom of routes.rb like match '*a', to: 'static_pages#error_404' so that any request not caught by earlier routes would be directed to an error_404 action which would render the template in static_pages/error_404.html.erb. This worked fine until I needed a catch-all route for something else (dynamic, database-backed pages and redirects), and alas, like the Highlander, there can only be one. So I then changed my strategy to catching 404-like errors in application_controller.rb: unless Rails.application.config.consider_all_requests_local rescue_from ActionController::RoutingError, with: :render_404 rescue_from ActionController::UnknownAction, with: :render_404 rescue_from ActiveRecord::RecordNotFound, with: :render_404 end def render_404<
here for a quick overview of the site Help Center Detailed answers to any questions you might http://stackoverflow.com/questions/15422040/custom-error-pages-with-thoughtbot-high-voltage have Meta Discuss the workings and policies of this site About Us Learn more about Stack Overflow the company Business Learn more about hiring developers or posting ads with us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack Overflow Community Stack Overflow is a community of 6.2 custom error million programmers, just like you, helping each other. Join them; it only takes a minute: Sign up Custom error pages with ThoughtBot High Voltage up vote 1 down vote favorite I'm using 1.2.2 of High Voltage, on a rails 3.2.2 app, and can't seem to get my app to fire a custom 404 when a custom error page page is not found - I just get the "Routing Error, No such page: " error page. Routes.rb: ... match '/signup', to: 'users#new' root :to => 'high_voltage/pages#show', :id => 'home' match '/404', :to => 'errors#not_found' match '/422', :to => 'errors#server_error' match '/500', :to => 'errors#server_error' match '/:id' => 'high_voltage/pages#show', :as => :static, :via => :get I have also set the following in application.rb (which I believe is the Rails 3.2 way of kicking off the routing errors): config.exceptions_app = self.routes But I still get the default Routing Error page. I've also tried using this in my app controller: unless config.consider_all_requests_local rescue_from Exception, :with => :render_500 rescue_from ActiveRecord::RecordNotFound, :with => :render_404 rescue_from ActionController::RoutingError, :with => :render_404 rescue_from ActionController::UnknownController, :with => :render_404 rescue_from ActionController::UnknownAction, :with => :render_404 end protected def render_500 exception logger.error exception.inspect render :template => "/errors/server_error.html.haml", :status => 500, :layout => 'application' end def render_404 exception logger.error exception.inspect render :template => "/errors/not_found.html.haml", :status => 404, :layout => 'application' end But it still doesn