# frozen_string_literal: truerequire"active_support/core_ext/module/attribute_accessors"require"rack/utils"moduleActionDispatchclassExceptionWrappercattr_accessor:rescue_responses,default: Hash.new(:internal_server_error).merge!("ActionController::RoutingError"=>:not_found,"AbstractController::ActionNotFound"=>:not_found,"ActionController::MethodNotAllowed"=>:method_not_allowed,"ActionController::UnknownHttpMethod"=>:method_not_allowed,"ActionController::NotImplemented"=>:not_implemented,"ActionController::UnknownFormat"=>:not_acceptable,"Mime::Type::InvalidMimeType"=>:not_acceptable,"ActionController::MissingExactTemplate"=>:not_acceptable,"ActionController::InvalidAuthenticityToken"=>:unprocessable_entity,"ActionController::InvalidCrossOriginRequest"=>:unprocessable_entity,"ActionDispatch::Http::Parameters::ParseError"=>:bad_request,"ActionController::BadRequest"=>:bad_request,"ActionController::ParameterMissing"=>:bad_request,"Rack::QueryParser::ParameterTypeError"=>:bad_request,"Rack::QueryParser::InvalidParameterError"=>:bad_request)cattr_accessor:rescue_templates,default: Hash.new("diagnostics").merge!("ActionView::MissingTemplate"=>"missing_template","ActionController::RoutingError"=>"routing_error","AbstractController::ActionNotFound"=>"unknown_action","ActiveRecord::StatementInvalid"=>"invalid_statement","ActionView::Template::Error"=>"template_error","ActionController::MissingExactTemplate"=>"missing_exact_template",)cattr_accessor:wrapper_exceptions,default: ["ActionView::Template::Error"]attr_reader:backtrace_cleaner,:exception,:wrapped_causes,:line_number,:filedefinitialize(backtrace_cleaner,exception)@backtrace_cleaner=backtrace_cleaner@exception=exception@wrapped_causes=wrapped_causes_for(exception,backtrace_cleaner)expand_backtraceifexception.is_a?(SyntaxError)||exception.cause.is_a?(SyntaxError)enddefunwrapped_exceptionifwrapper_exceptions.include?(exception.class.to_s)exception.causeelseexceptionendenddefrescue_template@@rescue_templates[@exception.class.name]enddefstatus_codeself.class.status_code_for_exception(unwrapped_exception.class.name)enddefapplication_traceclean_backtrace(:silent)enddefframework_traceclean_backtrace(:noise)enddeffull_traceclean_backtrace(:all)enddeftracesapplication_trace_with_ids=[]framework_trace_with_ids=[]full_trace_with_ids=[]full_trace.each_with_indexdo|trace,idx|trace_with_id={exception_object_id: @exception.object_id,id: idx,trace: trace}ifapplication_trace.include?(trace)application_trace_with_ids<<trace_with_idelseframework_trace_with_ids<<trace_with_idendfull_trace_with_ids<<trace_with_idend{"Application Trace"=>application_trace_with_ids,"Framework Trace"=>framework_trace_with_ids,"Full Trace"=>full_trace_with_ids}enddefself.status_code_for_exception(class_name)Rack::Utils.status_code(@@rescue_responses[class_name])enddefsource_extractsbacktrace.mapdo|trace|file,line_number=extract_file_and_line_number(trace){code: source_fragment(file,line_number),line_number: line_number}endenddeftrace_to_showiftraces["Application Trace"].empty?&&rescue_template!="routing_error""Full Trace"else"Application Trace"endenddefsource_to_show_id(traces[trace_to_show].first||{})[:id]endprivatedefbacktraceArray(@exception.backtrace)enddefcauses_for(exception)returnenum_for(__method__,exception)unlessblock_given?yieldexceptionwhileexception=exception.causeenddefwrapped_causes_for(exception,backtrace_cleaner)causes_for(exception).map{|cause|self.class.new(backtrace_cleaner,cause)}enddefclean_backtrace(*args)ifbacktrace_cleanerbacktrace_cleaner.clean(backtrace,*args)elsebacktraceendenddefsource_fragment(path,line)returnunlessRails.respond_to?(:root)&&Rails.rootfull_path=Rails.root.join(path)ifFile.exist?(full_path)File.open(full_path,"r")do|file|start=[line-3,0].maxlines=file.each_line.drop(start).take(6)Hash[*(start+1..(lines.count+start)).zip(lines).flatten]endendenddefextract_file_and_line_number(trace)# Split by the first colon followed by some digits, which works for both# Windows and Unix path styles.file,line=trace.match(/^(.+?):(\d+).*$/,&:captures)||trace[file,line.to_i]enddefexpand_backtrace@exception.backtrace.unshift(@exception.to_s.split("\n")).flatten!endendend