diff --git a/CHANGELOG.md b/CHANGELOG.md index 4289197b..487883f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ Airbrake Ruby Changelog * Started validating the 'environment' config option (a warning will be printed, if it is misconfigured) ([#115](https://github.com/airbrake/airbrake-ruby/pull/115)) +* Fixed error while filtering unparseable backtraces + ([#120](https://github.com/airbrake/airbrake-ruby/pull/120)) ### [v1.4.6][v1.4.6] (August 18, 2016) diff --git a/lib/airbrake-ruby/filter_chain.rb b/lib/airbrake-ruby/filter_chain.rb index 33e9f946..7bc7376a 100644 --- a/lib/airbrake-ruby/filter_chain.rb +++ b/lib/airbrake-ruby/filter_chain.rb @@ -13,7 +13,10 @@ class FilterChain notice[:errors].each do |error| Gem.path.each do |gem_path| error[:backtrace].each do |frame| - frame[:file].sub!(/\A#{gem_path}/, '[GEM_ROOT]'.freeze) + # If the frame is unparseable, then 'file' is nil, thus nothing to + # filter (all frame's data is in 'function' instead). + next unless (file = frame[:file]) + file.sub!(/\A#{gem_path}/, '[GEM_ROOT]'.freeze) end end end @@ -67,7 +70,8 @@ def root_directory_filter(root_directory) proc do |notice| notice[:errors].each do |error| error[:backtrace].each do |frame| - frame[:file].sub!(/\A#{root_directory}/, '[PROJECT_ROOT]'.freeze) + next unless (file = frame[:file]) + file.sub!(/\A#{root_directory}/, '[PROJECT_ROOT]'.freeze) end end end diff --git a/spec/filter_chain_spec.rb b/spec/filter_chain_spec.rb index 9e2490a6..34a40d42 100644 --- a/spec/filter_chain_spec.rb +++ b/spec/filter_chain_spec.rb @@ -152,6 +152,42 @@ to(change { notice.ignored? }.from(false).to(true)) end end + + context "gem root filter" do + let(:ex) do + AirbrakeTestError.new.tap do |error| + error.set_backtrace(['(unparseable/frame.rb:23)']) + end + end + + it "does not filter file if it is nil" do + config.logger = Logger.new('/dev/null') + notice = Airbrake::Notice.new(config, ex) + + expect(notice[:errors].first[:file]).to be_nil + expect { @chain.refine(notice) }. + not_to change { notice[:errors].first[:file] } + end + end + + context "root directory filter" do + let(:ex) do + AirbrakeTestError.new.tap do |error| + error.set_backtrace(['(unparseable/frame.rb:23)']) + end + end + + it "does not filter file if it is nil" do + config.logger = Logger.new('/dev/null') + config.root_directory = '/bingo/bango' + notice = Airbrake::Notice.new(config, ex) + filter_chain = described_class.new(config) + + expect(notice[:errors].first[:file]).to be_nil + expect { filter_chain.refine(notice) }. + not_to change { notice[:errors].first[:file] } + end + end end end end