Skip to content

Commit

Permalink
Correctly handle exceptions where backtrace_locations is nil. (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix authored Nov 30, 2023
1 parent 77382fd commit 4000137
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
16 changes: 15 additions & 1 deletion lib/sus/output/backtrace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,21 @@ def self.first(identity = nil)
def self.for(exception, identity = nil)
# I've disabled the root filter here, because partial backtraces are not very useful.
# We might want to do something to improve presentation of the backtrace based on the root instead.
self.new(exception.backtrace_locations, identity&.path)
self.new(extract_stack(exception), identity&.path)
end

Location = Struct.new(:path, :lineno, :label)

def self.extract_stack(exception)
if stack = exception.backtrace_locations
return stack
elsif stack = exception.backtrace
return stack.map do |line|
Location.new(*line.split(":", 3))
end
else
[]
end
end

def initialize(stack, root = nil, limit = nil)
Expand Down
16 changes: 16 additions & 0 deletions test/sus/output/backtrace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,20 @@
expect(stack.last.path).to be(:start_with?, identity.path)
end
end

with "a wonky exception" do
let(:exception) {Exception.new}

it "has a backtrace" do
# This causes the exception to have a backtrace but not backtrace_locations.
exception.set_backtrace(caller)

stack = subject.extract_stack(exception)
expect(stack).to be_a(Array)
expect(stack).to have_attributes(size: be >= 1)

# This is a compatibility wrapper...
expect(stack.first).to be_a(Sus::Output::Backtrace::Location)
end
end
end

0 comments on commit 4000137

Please sign in to comment.