Changeset 6307
- Timestamp:
- 03/04/07 12:31:21 (2 years ago)
- Files:
-
- trunk/railties/lib/dispatcher.rb (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/railties/lib/dispatcher.rb
r5794 r6307 40 40 end 41 41 rescue Exception => exception # errors from CGI dispatch 42 failsafe_response( output, '500 Internal Server Error', exception) do42 failsafe_response(cgi, output, '500 Internal Server Error', exception) do 43 43 controller ||= ApplicationController rescue LoadError nil 44 44 controller ||= ActionController::Base … … 91 91 attr_accessor_with_default :preparation_callbacks_run, false 92 92 alias_method :preparation_callbacks_run?, :preparation_callbacks_run 93 93 94 94 # CGI.new plus exception handling. CGI#read_multipart raises EOFError 95 95 # if body.empty? or body.size != Content-Length and raises ArgumentError 96 96 # if Content-Length is non-integer. 97 97 def new_cgi(output) 98 failsafe_response( output, '400 Bad Request') { CGI.new }98 failsafe_response(nil, output, '400 Bad Request') { CGI.new } 99 99 end 100 100 … … 132 132 133 133 # If the block raises, send status code as a last-ditch response. 134 def failsafe_response( output, status, exception = nil)134 def failsafe_response(cgi, fallback_output, status, exception = nil) 135 135 yield 136 rescue Exception # errors from executed block136 rescue Exception 137 137 begin 138 output.write "Status: #{status}\r\n" 139 140 if exception 141 message = exception.to_s + "\r\n" + exception.backtrace.join("\r\n") 142 error_path = File.join(RAILS_ROOT, 'public', '500.html') 138 log_failsafe_exception(cgi, status, exception) 143 139 144 if defined?(RAILS_DEFAULT_LOGGER) && !RAILS_DEFAULT_LOGGER.nil? 145 RAILS_DEFAULT_LOGGER.fatal(message) 140 body = failsafe_response_body(status) 141 if cgi 142 head = { 'status' => status, 'type' => 'text/html' } 146 143 147 output.write "Content-Type: text/html\r\n\r\n" 144 # FIXME: using CGI differently than CGIResponse does breaks 145 # the Mongrel CGI wrapper. 146 if defined?(Mongrel) && cgi.is_a?(Mongrel::CGIWrapper) 147 # FIXME: set a dummy cookie so the Mongrel CGI wrapper will 148 # also consider @output_cookies (used for session cookies.) 149 head['cookie'] = [] 150 cgi.header(head) 151 fallback_output << body 152 else 153 cgi.out(head) { body } 154 end 155 else 156 fallback_output.write "Status: #{status}\r\nContent-Type: text/html\r\n\r\n#{body}" 157 end 158 nil 159 rescue Exception # Logger or IO errors 160 end 161 end 148 162 149 if File.exists?(error_path) 150 output.write(IO.read(error_path)) 151 else 152 output.write("<html><body><h1>Application error (Rails)</h1></body></html>") 153 end 154 else 155 output.write "Content-Type: text/plain\r\n\r\n" 156 output.write(message) 157 end 158 end 159 rescue Exception # Logger or IO errors 163 def failsafe_response_body(status) 164 error_path = "#{RAILS_ROOT}/public/#{status[0..3]}.html" 165 166 if File.exists?(error_path) 167 File.read(error_path) 168 else 169 "<html><body><h1>#{status}</h1></body></html>" 170 end 171 end 172 173 def log_failsafe_exception(cgi, status, exception) 174 fell_back = cgi ? 'has cgi' : 'no cgi, fallback ouput' 175 message = "DISPATCHER FAILSAFE RESPONSE (#{fell_back}) #{Time.now}\n Status: #{status}\n" 176 message << " #{exception}\n #{exception.backtrace.join("\n ")}" if exception 177 failsafe_logger.fatal message 178 end 179 180 def failsafe_logger 181 if defined?(RAILS_DEFAULT_LOGGER) && !RAILS_DEFAULT_LOGGER.nil? 182 RAILS_DEFAULT_LOGGER 183 else 184 Logger.new($stderr) 160 185 end 161 186 end