Skip to content

Commit

Permalink
Merge pull request #4 from airbrake/generic-backtraces-support
Browse files Browse the repository at this point in the history
backtrace: add support for generic backtraces
  • Loading branch information
kyrylo committed Dec 18, 2015
2 parents 548c0bc + b31d680 commit 3b3e0fa
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
Airbrake Ruby Changelog
=======================

### [v1.0.0][v1.0.0] (December 17, 2015)

* Improved backtrace parsing support ([#4](https://github.com/airbrake/airbrake-ruby/pull/4))

### [v1.0.0.rc.1][v1.0.0.rc.1] (December 11, 2015)

* Initial release

[v1.0.0.rc.1]: https://github.com/airbrake/airbrake-ruby/releases/tag/v1.0.0.rc.1
[v1.0.0]: https://github.com/airbrake/airbrake-ruby/releases/tag/v1.0.0
26 changes: 23 additions & 3 deletions lib/airbrake-ruby/backtrace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module Backtrace
##
# @return [Regexp] the pattern that matches standard Ruby stack frames,
# such as ./spec/notice_spec.rb:43:in `block (3 levels) in <top (required)>'
STACKFRAME_REGEXP = %r{\A
RUBY_STACKFRAME_REGEXP = %r{\A
(?<file>.+) # Matches './spec/notice_spec.rb'
:
(?<line>\d+) # Matches '43'
Expand All @@ -34,6 +34,16 @@ module Backtrace
\)
\z/x

##
# @return [Regexp] the template that tries to assume what a generic stack
# frame might look like, when exception's backtrace is set manually.
GENERIC_STACKFRAME_REGEXP = %r{\A
(?<file>.+) # Matches '/foo/bar/baz.ext'
:
(?<line>\d+) # Matches '43'
(?<function>) # No-op
\z}x

##
# Parses an exception's backtrace.
#
Expand All @@ -44,11 +54,11 @@ def self.parse(exception)
regexp = if java_exception?(exception)
JAVA_STACKFRAME_REGEXP
else
STACKFRAME_REGEXP
RUBY_STACKFRAME_REGEXP
end

(exception.backtrace || []).map do |stackframe|
stack_frame(regexp.match(stackframe))
stack_frame(match_frame(regexp, stackframe))
end
end

Expand All @@ -71,5 +81,15 @@ def stack_frame(match)
function: match[:function] }
end
end

def self.match_frame(regexp, stackframe)
match = regexp.match(stackframe)
return match if match

match = GENERIC_STACKFRAME_REGEXP.match(stackframe)
return match if match

raise Airbrake::Error, "can't parse '#{stackframe}'"
end
end
end
35 changes: 35 additions & 0 deletions spec/backtrace_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,40 @@
to eq(backtrace_array)
end
end

context "generic backtrace" do
# rubocop:disable Metrics/LineLength
let(:generic_bt) do
["/home/bingo/bango/assets/stylesheets/error_pages.scss:139:in `animation'",
"/home/bingo/bango/assets/stylesheets/error_pages.scss:139",
"/home/bingo/.gem/ruby/2.2.2/gems/sass-3.4.20/lib/sass/tree/visitors/perform.rb:349:in `block in visit_mixin'"]
end
# rubocop:enable Metrics/LineLength

let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(generic_bt) } }

let(:parsed_backtrace) do
# rubocop:disable Metrics/LineLength, Style/HashSyntax, Style/SpaceInsideHashLiteralBraces, Style/SpaceAroundOperators
[{:file=>"/home/bingo/bango/assets/stylesheets/error_pages.scss", :line=>139, :function=>"animation"},
{:file=>"/home/bingo/bango/assets/stylesheets/error_pages.scss", :line=>139, :function=>""},
{:file=>"/home/bingo/.gem/ruby/2.2.2/gems/sass-3.4.20/lib/sass/tree/visitors/perform.rb", :line=>349, :function=>"block in visit_mixin"}]
# rubocop:enable Metrics/LineLength, Style/HashSyntax, Style/SpaceInsideHashLiteralBraces, Style/SpaceAroundOperators
end

it "returns a properly formatted array of hashes" do
expect(described_class.parse(ex)).to eq(parsed_backtrace)
end
end

context "unknown backtrace" do
let(:unknown_bt) { ['a b c 1 23 321 .rb'] }

let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(unknown_bt) } }

it "raises error" do
expect { described_class.parse(ex) }.
to raise_error(Airbrake::Error, /can't parse/)
end
end
end
end

0 comments on commit 3b3e0fa

Please sign in to comment.