aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware/show_exceptions.rb')
-rw-r--r--actionpack/lib/action_dispatch/middleware/show_exceptions.rb48
1 files changed, 27 insertions, 21 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
index e095b51342..dbe3206808 100644
--- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb
@@ -6,8 +6,6 @@ module ActionDispatch
# This middleware rescues any exception returned by the application and renders
# nice exception pages if it's being rescued locally.
class ShowExceptions
- LOCALHOST = [/^127\.0\.0\.\d{1,3}$/, "::1", /^0:0:0:0:0:0:0:1(%.*)?$/].freeze
-
RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates')
cattr_accessor :rescue_responses
@@ -45,28 +43,29 @@ module ActionDispatch
end
def call(env)
- status, headers, body = @app.call(env)
-
- # Only this middleware cares about RoutingError. So, let's just raise
- # it here.
- # TODO: refactor this middleware to handle the X-Cascade scenario without
- # having to raise an exception.
- if headers['X-Cascade'] == 'pass'
- raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}"
+ begin
+ status, headers, body = @app.call(env)
+ exception = nil
+
+ # Only this middleware cares about RoutingError. So, let's just raise
+ # it here.
+ if headers['X-Cascade'] == 'pass'
+ raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}"
+ end
+ rescue Exception => exception
+ raise exception if env['action_dispatch.show_exceptions'] == false
end
- [status, headers, body]
- rescue Exception => exception
- raise exception if env['action_dispatch.show_exceptions'] == false
- render_exception(env, exception)
+ exception ? render_exception(env, exception) : [status, headers, body]
end
private
def render_exception(env, exception)
log_error(exception)
+ exception = original_exception(exception)
request = Request.new(env)
- if @consider_all_requests_local || local_request?(request)
+ if @consider_all_requests_local || request.local?
rescue_action_locally(request, exception)
else
rescue_action_in_public(exception)
@@ -112,11 +111,6 @@ module ActionDispatch
end
end
- # True if the request came from localhost, 127.0.0.1.
- def local_request?(request)
- LOCALHOST.any? { |local_ip| local_ip === request.remote_addr && local_ip === request.remote_ip }
- end
-
def status_code(exception)
Rack::Utils.status_code(@@rescue_responses[exception.class.name])
end
@@ -134,7 +128,7 @@ module ActionDispatch
ActiveSupport::Deprecation.silence do
message = "\n#{exception.class} (#{exception.message}):\n"
- message << exception.annoted_source_code if exception.respond_to?(:annoted_source_code)
+ message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
message << " " << application_trace(exception).join("\n ")
logger.fatal("#{message}\n\n")
end
@@ -161,5 +155,17 @@ module ActionDispatch
def logger
defined?(Rails.logger) ? Rails.logger : Logger.new($stderr)
end
+
+ def original_exception(exception)
+ if registered_original_exception?(exception)
+ exception.original_exception
+ else
+ exception
+ end
+ end
+
+ def registered_original_exception?(exception)
+ exception.respond_to?(:original_exception) && @@rescue_responses.has_key?(exception.original_exception.class.name)
+ end
end
end