Skip to content

Commit 3ec2f19

Browse files
authored
Merge pull request rails#50305 from MaxLap/log_cause_trace_debug_exceptions
Log trace of causes for unhandled exceptions
2 parents 4a4b399 + f47ef36 commit 3ec2f19

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

actionpack/lib/action_dispatch/middleware/debug_exceptions.rb

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,30 @@ def log_error(request, wrapper)
142142

143143
message = []
144144
message << " "
145-
message << "#{wrapper.exception_class_name} (#{wrapper.message}):"
146145
if wrapper.has_cause?
147-
message << "\nCauses:"
146+
message << "#{wrapper.exception_class_name} (#{wrapper.message})"
148147
wrapper.wrapped_causes.each do |wrapped_cause|
149-
message << "#{wrapped_cause.exception_class_name} (#{wrapped_cause.message})"
148+
message << "Caused by: #{wrapped_cause.exception_class_name} (#{wrapped_cause.message})"
150149
end
150+
151+
message << "\nInformation for: #{wrapper.exception_class_name} (#{wrapper.message}):"
152+
else
153+
message << "#{wrapper.exception_class_name} (#{wrapper.message}):"
151154
end
155+
152156
message.concat(wrapper.annotated_source_code)
153157
message << " "
154158
message.concat(trace)
155159

160+
if wrapper.has_cause?
161+
wrapper.wrapped_causes.each do |wrapped_cause|
162+
message << "\nInformation for cause: #{wrapped_cause.exception_class_name} (#{wrapped_cause.message}):"
163+
message.concat(wrapped_cause.annotated_source_code)
164+
message << " "
165+
message.concat(wrapped_cause.exception_trace)
166+
end
167+
end
168+
156169
log_array(logger, message, request)
157170
end
158171

actionpack/test/dispatch/debug_exceptions_test.rb

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -627,11 +627,43 @@ def self.build_app(app, *args)
627627
get "/nested_exceptions", headers: env
628628
assert_response 500
629629
log = output.rewind && output.read
630-
assert_includes log, <<~MSG
631-
Causes:
632-
RuntimeError (Second error)
633-
RuntimeError (First error)
630+
631+
# Splitting into paragraphs to be easier to see difference/error when there is one
632+
paragraphs = log.split(/\n\s*\n/)
633+
634+
assert_includes(paragraphs[0], <<~MSG.strip)
635+
RuntimeError (Third error)
636+
Caused by: RuntimeError (Second error)
637+
Caused by: RuntimeError (First error)
638+
MSG
639+
640+
assert_includes(paragraphs[1], <<~MSG.strip)
641+
Information for: RuntimeError (Third error):
642+
MSG
643+
644+
assert_match Regexp.new(<<~REGEX.strip), paragraphs[2].lines[0..2].join
645+
\\A.*in `rescue in rescue in raise_nested_exceptions'
646+
.*in `rescue in raise_nested_exceptions'
647+
.*in `raise_nested_exceptions'
648+
REGEX
649+
650+
assert_includes(paragraphs[3], <<~MSG.strip)
651+
Information for cause: RuntimeError (Second error):
652+
MSG
653+
654+
assert_match Regexp.new(<<~REGEX.strip), paragraphs[4].lines[0..1].join
655+
\\A.*in `rescue in raise_nested_exceptions'
656+
.*in `raise_nested_exceptions'
657+
REGEX
658+
659+
660+
assert_includes(paragraphs[5], <<~MSG.strip)
661+
Information for cause: RuntimeError (First error):
634662
MSG
663+
664+
assert_match Regexp.new(<<~REGEX.strip), paragraphs[6].lines[0]
665+
\\A.*in `raise_nested_exceptions'
666+
REGEX
635667
end
636668

637669
test "display backtrace when error type is SyntaxError" do

0 commit comments

Comments
 (0)