JSON responses for 404 and 500 errors in rails

Rails proves to be very much helpful in creating REST APIs. Hence, while you are creating a REST API you would never want to render HTML pages for your 404(page not found) and 500(internal server) errors. This post will help you to return JSON responses instead of the default HTML templates for the same.

Prior to rails 3 you could do this easily and write the code below inside your application controller.

class ApplicationController < ActionController::Base
  rescue_from(ActionController::RoutingError) {
    render :json => {:error_message => "The resource you were looking for does not exist"}
  rescue_from(Exception) {
    render :json => {:error_message => "We're sorry, but something went wrong. We've been notified about this issue and we'll take a look at it shortly."}

But with the advent of ActionDispatch in Rails 3.0 all the routing has been moved to rack DSL. Hence, now we cannot catch the ActionController::RoutingError inside of our ApplicationController, as the rack DSL will automatically give the response to the client even before the request reaches your code.

So, in order to achieve the functionality we need, we will have to change the way the routing exceptions are handled inside ActionDispatch::ShowExceptions

Step 1: Create a initializer file show_exceptions.rb inside config/initializers directory, and use the code blow:

# A Custom Exception Handler
# This will call the ErrorsController when a 404 or 500 response is to be sent

require 'action_dispatch/middleware/show_exceptions'

module ActionDispatch
  class ShowExceptions
      def render_exception_with_template(env, exception)
        body = ExceptionsController.action(rescue_responses[exception.class.name]).call(env)
        body[1]['Content-Type']= "application/json; charset=utf-8"
          render_exception_without_template(env, exception)

      alias_method_chain :render_exception, :template

This will give a call to the appropriate exception handler action inside of ExceptionsController.

Step: 2: Create ErrorsController, and use the code below

class ErrorsController < ApplicationController
  ERRORS = [

  ERRORS.each do |e|
    define_method e do
      message = e == :not_found ? "The request resource was not found" : "We're sorry, but something went wrong. We've been notified about this issue and we'll take a look at it shortly."

      respond_to do |format|
        format.any {render :json => {:error_message => message}, :status => e}

That’s all that is required to give a custom json response for 404 and 500 errors for your restful rails applications.


  1. This is not working for me. I still get the same old HTML response. I set a debugger in the show_exceptions.rb and it’s not even getting there. What else do I need to do? Where do I place the ErrorsController? I placed it in a directory in app/controllers.

      1. this is the way i’m using right now in rails4 and seems to works smoothly:

        anyway, it was strange for me to se you suggest ExceptionsController(.rb?) file to implement ErrorsController, but i’m not sure this was the problem, because i tried to rename che class name with no luck …

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s