lib/timber/integrations/rack/exception_event.rb in timber-2.0.24 vs lib/timber/integrations/rack/exception_event.rb in timber-2.1.0.rc1

- old
+ new

@@ -1,28 +1,61 @@ +begin + require "action_dispatch/middleware/exception_wrapper" +rescue Exception +end + +require "timber/integrations/rack/middleware" + module Timber module Integrations module Rack - # Reponsible for capturing exceptions events within a Rack stack. - class ExceptionEvent - def initialize(app) - @app = app + # A Rack middleware that is reponsible for capturing exceptions events + # {Timber::Events::Exception}. + class ExceptionEvent < Middleware + # We determine this when the app loads to avoid the overhead on a per request basis. + EXCEPTION_WRAPPER_TAKES_CLEANER = if Gem.loaded_specs["rails"] + Gem.loaded_specs["rails"].version >= Gem::Version.new('5.0.0') + else + false end def call(env) begin status, headers, body = @app.call(env) rescue Exception => exception Config.instance.logger.fatal do + backtrace = extract_backtrace(env, exception) + Events::Exception.new( name: exception.class.name, exception_message: exception.message, - backtrace: exception.backtrace + backtrace: backtrace ) end raise exception end end + + private + # Rails provides a backtrace cleaner, so we use it here. + def extract_backtrace(env, exception) + if defined?(::ActionDispatch::ExceptionWrapper) + wrapper = if EXCEPTION_WRAPPER_TAKES_CLEANER + request = Util::Request.new(env) + backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner") + ::ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception) + else + ::ActionDispatch::ExceptionWrapper.new(env, exception) + end + + trace = wrapper.application_trace + trace = wrapper.framework_trace if trace.empty? + trace + else + exception.backtrace + end + end end end end end \ No newline at end of file