Configure local_request

Neeraj Singh

By Neeraj Singh

on February 5, 2009

How does Rails handle exceptions ?

Rails exception handling depends on two factors and we are going to discuss both of them here.

1# ~/lib/action_controller/rescue.rb
2if consider_all_requests_local || local_request?
3  rescue_action_locally(exception)
4else
5  rescue_action_in_public(exception)
6end

When exceptions are handled by rescue_action_locally then we get to see the page with stacktrace. When exceptions are handled by rescue_action_in_public, we get to see the public/500.html or an error page matching the error code.

As you can see Rails uses two different methods consider_all_requests_local and local_request? to decide how exception should be handled.

Method consider_all_requests_local

consider_all_requests_local is a class level variable for ActionController::Base . We hardly pay attention to it but it is configured through files residing in config/environments

1# config/environments/development.rb
2config.action_controller.consider_all_requests_local = true
3
4# config/environments/production.rb
5config.action_controller.consider_all_requests_local = false

As you can see in development environment all the requests are considered local.

I have overridden the method local_request? but I am still not able to see public page when exception is raised.

That is a common question I see in the mailing list. As you can see the condition to decide how to handle exception is

1if consider_all_requests_local || local_request?

In development environment consider_all_requests_local is always true as I showed before. Since one of the conditions is true Rails always handles the exception using rescue_action_locally .

I am running in production mode but I am still not able to see public/500.html page when I get exception at http://localhost:3000.

Same issue. In this case you are running in production mode so consider_all_requests_local is false but local_request? is still true because of localhost.

I want local_request? to be environment dependent

Recently I started using hoptoad and I needed to test how hoptoad will handle exception in production mode. However without any change local_request? was always returning true for http://localhost:30000 .

Then I stick following file under config/initializers

1# config/initializers/local_request_override.rb
2module CustomRescue
3  def local_request?
4    return false if Rails.env.production? || Rails.env.staging?
5    super
6  end
7end
8
9ActionController::Base.class_eval do
10  include CustomRescue
11end

Now all request in production or in staging mode are treated as NOT local.

Now in both staging and production mode I get to see 500.html page even if I am accessing the application from http://localhost:3000 .

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.