Skip to content

Commit 4000137

Browse files
authored
Correctly handle exceptions where backtrace_locations is nil. (#37)
1 parent 77382fd commit 4000137

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

lib/sus/output/backtrace.rb

+15-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,21 @@ def self.first(identity = nil)
1515
def self.for(exception, identity = nil)
1616
# I've disabled the root filter here, because partial backtraces are not very useful.
1717
# We might want to do something to improve presentation of the backtrace based on the root instead.
18-
self.new(exception.backtrace_locations, identity&.path)
18+
self.new(extract_stack(exception), identity&.path)
19+
end
20+
21+
Location = Struct.new(:path, :lineno, :label)
22+
23+
def self.extract_stack(exception)
24+
if stack = exception.backtrace_locations
25+
return stack
26+
elsif stack = exception.backtrace
27+
return stack.map do |line|
28+
Location.new(*line.split(":", 3))
29+
end
30+
else
31+
[]
32+
end
1933
end
2034

2135
def initialize(stack, root = nil, limit = nil)

test/sus/output/backtrace.rb

+16
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,20 @@
2626
expect(stack.last.path).to be(:start_with?, identity.path)
2727
end
2828
end
29+
30+
with "a wonky exception" do
31+
let(:exception) {Exception.new}
32+
33+
it "has a backtrace" do
34+
# This causes the exception to have a backtrace but not backtrace_locations.
35+
exception.set_backtrace(caller)
36+
37+
stack = subject.extract_stack(exception)
38+
expect(stack).to be_a(Array)
39+
expect(stack).to have_attributes(size: be >= 1)
40+
41+
# This is a compatibility wrapper...
42+
expect(stack.first).to be_a(Sus::Output::Backtrace::Location)
43+
end
44+
end
2945
end

0 commit comments

Comments
 (0)