3
module ActionController
4
# The Failsafe middleware is usually the top-most middleware in the Rack
5
# middleware chain. It returns the underlying middleware's response, but if
6
# the underlying middle raises an exception then Failsafe will log the
7
# exception into the Rails log file, and will attempt to return an error
10
# Failsafe is a last resort for logging errors and for telling the HTTP
11
# client that something went wrong. Do not confuse this with the
12
# ActionController::Rescue module, which is responsible for catching
13
# exceptions at deeper levels. Unlike Failsafe, which is as simple as
14
# possible, Rescue provides features that allow developers to hook into
15
# the error handling logic, and can customize the error message response
16
# based on the HTTP client's IP.
18
cattr_accessor :error_file_path
19
self.error_file_path = Rails.public_path if defined?(Rails.public_path)
27
rescue Exception => exception
28
# Reraise exception in test environment
29
if defined?(Rails) && Rails.env.test?
32
failsafe_response(exception)
37
def failsafe_response(exception)
38
log_failsafe_exception(exception)
39
[500, {'Content-Type' => 'text/html'}, [failsafe_response_body]]
40
rescue Exception => failsafe_error # Logger or IO errors
41
$stderr.puts "Error during failsafe response: #{failsafe_error}"
44
def failsafe_response_body
45
error_template_path = "#{self.class.error_file_path}/500.html"
46
if File.exist?(error_template_path)
48
result = render_template(error_template_path)
56
result = "<html><body><h1>500 Internal Server Error</h1>" <<
57
"If you are the administrator of this website, then please read this web " <<
58
"application's log file to find out what went wrong.</body></html>"
63
# The default 500.html uses the h() method.
68
def render_template(filename)
69
ERB.new(File.read(filename)).result(binding)
72
def log_failsafe_exception(exception)
73
message = "/!\\ FAILSAFE /!\\ #{Time.now}\n Status: 500 Internal Server Error\n"
74
message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception
75
failsafe_logger.fatal(message)
79
if defined?(Rails) && Rails.logger