Skip to content

Commit acca59c

Browse files
committed
Don't let backtrace_cleanup_callback affect abs_path
At some point, rails added a [default gem filter to their `BacktraceCleaner`](https://github.com/rails/rails/blob/a8709e6ea26eca73a652af4fdd0a9f7db5352af4/activesupport/lib/active_support/backtrace_cleaner.rb#L118-L125) which messed up our linecache/context lines parsing logic since we get paths like ``` activesupport (7.1.2) lib/active_support/callbacks.rb ``` instead of raw paths. This PR cleans up handling this case by making a clear distinction between `abs_path` and `filename` as was intended in the original relay protocol and we were never populating these properly.
1 parent a9b3687 commit acca59c

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

sentry-ruby/lib/sentry/backtrace.rb

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class Line
1818
# org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
1919
JAVA_INPUT_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/
2020

21+
# The absolute path in the backtrace
22+
attr_reader :abs_path
23+
2124
# The file portion of the line (such as app/models/user.rb)
2225
attr_reader :file
2326

@@ -35,25 +38,33 @@ class Line
3538
# Parses a single line of a given backtrace
3639
# @param [String] unparsed_line The raw line from +caller+ or some backtrace
3740
# @return [Line] The parsed backtrace line
38-
def self.parse(unparsed_line, in_app_pattern = nil)
39-
ruby_match = unparsed_line.match(RUBY_INPUT_FORMAT)
40-
if ruby_match
41-
_, file, number, _, method = ruby_match.to_a
42-
file.sub!(/\.class$/, RB_EXTENSION)
43-
module_name = nil
44-
else
41+
def self.parse(unparsed_line, in_app_pattern = nil, cleaned_line = nil)
42+
if RUBY_PLATFORM == "java"
4543
java_match = unparsed_line.match(JAVA_INPUT_FORMAT)
46-
_, module_name, method, file, number = java_match.to_a
44+
_, module_name, method, abs_path, number = java_match.to_a
45+
file = nil
46+
else
47+
ruby_match = unparsed_line.match(RUBY_INPUT_FORMAT)
48+
if ruby_match
49+
_, abs_path, number, _, method = ruby_match.to_a
50+
abs_path.sub!(/\.class$/, RB_EXTENSION)
51+
module_name = nil
52+
end
53+
54+
cleaned_match = cleaned_line.match(RUBY_INPUT_FORMAT) if cleaned_line
55+
file = cleaned_match[1] if cleaned_match
4756
end
48-
new(file, number, method, module_name, in_app_pattern)
57+
58+
new(abs_path, number, method, module_name, in_app_pattern, file)
4959
end
5060

51-
def initialize(file, number, method, module_name, in_app_pattern)
52-
@file = file
61+
def initialize(abs_path, number, method, module_name, in_app_pattern, file = nil)
62+
@abs_path = abs_path
5363
@module_name = module_name
5464
@number = number.to_i
5565
@method = method
5666
@in_app_pattern = in_app_pattern
67+
@file = file
5768
end
5869

5970
def in_app
@@ -86,14 +97,14 @@ def inspect
8697
def self.parse(backtrace, project_root, app_dirs_pattern, &backtrace_cleanup_callback)
8798
ruby_lines = backtrace.is_a?(Array) ? backtrace : backtrace.split(/\n\s*/)
8899

89-
ruby_lines = backtrace_cleanup_callback.call(ruby_lines) if backtrace_cleanup_callback
100+
cleaned_lines = backtrace ? backtrace_cleanup_callback.call(ruby_lines) : []
90101

91102
in_app_pattern ||= begin
92103
Regexp.new("^(#{project_root}/)?#{app_dirs_pattern}")
93104
end
94105

95-
lines = ruby_lines.to_a.map do |unparsed_line|
96-
Line.parse(unparsed_line, in_app_pattern)
106+
lines = ruby_lines.to_a.zip(cleaned_lines).map do |unparsed_line, cleaned_line|
107+
Line.parse(unparsed_line, in_app_pattern, cleaned_line)
97108
end
98109

99110
new(lines)

sentry-ruby/lib/sentry/interfaces/stacktrace.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ def initialize(project_root, line, strip_backtrace_load_path = true)
3131
@project_root = project_root
3232
@strip_backtrace_load_path = strip_backtrace_load_path
3333

34-
@abs_path = line.file
34+
@abs_path = line.abs_path
3535
@function = line.method if line.method
3636
@lineno = line.number
3737
@in_app = line.in_app
3838
@module = line.module_name if line.module_name
39-
@filename = compute_filename
39+
# if the backtrace_cleanup_callback already gave us a nice file, we don't do the stripping again
40+
@filename = line.file || compute_filename
4041
end
4142

4243
def to_s

0 commit comments

Comments
 (0)