We write about Ruby on Rails, React.js, React Native, remote work, open source, engineering and design.
How does Rails handle exceptions ?
Rails exception handling depends on two factors and we are going to discuss both of them here.
# ~/lib/action_controller/rescue.rb if consider_all_requests_local || local_request? rescue_action_locally(exception) else rescue_action_in_public(exception) end
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
local_request? to decide how exception should be handled.
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/development.rb config.action_controller.consider_all_requests_local = true # config/environments/production.rb config.action_controller.consider_all_requests_local = false
As you can see in development environment all the requests are considered local.
That is a common question I see in the mailing list. As you can see the condition to decide how to handle exception is
if 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 .
Same issue. In this case you are running in production mode so
false but local_request? is still true because of localhost.
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
Then I stick following file under
# config/initializers/local_request_override.rb module CustomRescue def local_request? return false if Rails.env.production? || Rails.env.staging? super end end ActionController::Base.class_eval do include CustomRescue end
Now all request in production or in staging mode are treated as NOT local.
Now in both
production mode I get to see 500.html page even if I am accessing the application from