diff --git a/lib/bugsnag/stacktrace.rb b/lib/bugsnag/stacktrace.rb index fceabb004..55e14a234 100644 --- a/lib/bugsnag/stacktrace.rb +++ b/lib/bugsnag/stacktrace.rb @@ -7,6 +7,9 @@ class Stacktrace # e.g. "org.jruby.Ruby.runScript(Ruby.java:807)" JAVA_BACKTRACE_REGEX = /^(.*)\((.*)(?::([0-9]+))?\)$/ + # Path to vendored code. Used to mark file paths as out of project. + VENDOR_PATH = 'vendor/' + def initialize(backtrace, configuration) @configuration = configuration @@ -31,7 +34,6 @@ def initialize(backtrace, configuration) # Generate the stacktrace line hash trace_hash = {} - trace_hash[:inProject] = true if in_project?(file) trace_hash[:lineNumber] = line_str.to_i if configuration.send_code @@ -40,9 +42,12 @@ def initialize(backtrace, configuration) # Clean up the file path in the stacktrace if defined?(@configuration.project_root) && @configuration.project_root.to_s != '' + trace_hash[:inProject] = true if file.start_with?(@configuration.project_root) file.sub!(/#{@configuration.project_root}\//, "") + trace_hash.delete(:inProject) if file.start_with?(VENDOR_PATH) end + # Strip common gem path prefixes if defined?(Gem) file = Gem.path.inject(file) {|line, path| line.sub(/#{path}\//, "") } @@ -67,10 +72,6 @@ def to_a private - def in_project?(line) - @configuration.project_root && line.start_with?(@configuration.project_root.to_s) - end - def code(file, line_number, num_lines = 7) code_hash = {} diff --git a/spec/report_spec.rb b/spec/report_spec.rb index 1a1f995c7..52ad13aee 100644 --- a/spec/report_spec.rb +++ b/spec/report_spec.rb @@ -524,6 +524,34 @@ def gloops } end + it 'marks vendored stack frames as out-of-project' do + project_root = File.expand_path File.dirname(__FILE__) + Bugsnag.configuration.project_root = project_root + + ex = Exception.new('Division by zero') + allow(ex).to receive (:backtrace) {[ + File.join(project_root, "vendor/strutils/lib/string.rb:508:in `splice'"), + File.join(project_root, "vendors/strutils/lib/string.rb:508:in `splice'"), + File.join(project_root, "lib/helpers/string.rb:32:in `splice'"), + File.join(project_root, "lib/vendor/lib/article.rb:158:in `initialize'"), + File.join(project_root, "lib/prog.rb:158:in `read_articles'"), + "app.rb:10:in `main'", + "(pry):3:in `__pry__'" + ]} + Bugsnag.notify(ex) + expect(Bugsnag).to have_sent_notification{ |payload| + exception = get_exception_from_payload(payload) + + expect(exception["stacktrace"][0]["inProject"]).to be_nil + expect(exception["stacktrace"][1]["inProject"]).to be true + expect(exception["stacktrace"][2]["inProject"]).to be true + expect(exception["stacktrace"][3]["inProject"]).to be true + expect(exception["stacktrace"][4]["inProject"]).to be true + expect(exception["stacktrace"][5]["inProject"]).to be_nil + expect(exception["stacktrace"][6]["inProject"]).to be_nil + } + end + it "adds app_version to the payload if it is set" do Bugsnag.configuration.app_version = "1.1.1" Bugsnag.notify(BugsnagTestException.new("It crashed"))