sentry-ruby-core 4.8.2 → 4.9.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09a04a594b731f8d13770650138f1abd5bce410dad2f4cb4da1a2caa5ef7eba2'
4
- data.tar.gz: e87cac23635525aa1b53772e262706a10948b52b634fafeedaf241c8b6d90c9a
3
+ metadata.gz: 4cf9f47960b6d555a19ee4859d686f535b238a0046999039b1bd24958d8a65cf
4
+ data.tar.gz: 7c99f67a943ed2cd8cc5f2c006aeb8b9dd89664997abacb83133d11ebeca2904
5
5
  SHA512:
6
- metadata.gz: db6311ce62c548e835cbc49c7616ac244d853c3206599e1b540035b16da97bf05cd52a81602cf30215f15ee3e675d6857cdba628f87fc631e73d63d9523081d5
7
- data.tar.gz: ae31de8f2bab17f15f16c8e6fea3fbbc359efc39c5f2ec5afba9fbfccbd4e77c22f051cd2b94278ff9c3ce92289448cccf1af8fc5df5da1fd7f25bb81458ae29
6
+ metadata.gz: 4e049ffe7513c8f78274093ff3f4f2ef6e754b442611352525453d9c040fb30391e63fd5e668c83e464e3b3293d003aa4944f00b66741a66176ad913a47949db
7
+ data.tar.gz: 8f0b9a6cef78cdab2804ffa2a3dd6de029672430ade59d907f6c1d60f6143817445d5c79524e0a1a66e95ffe0c2acba2b0a93af844057b172ec1fbb8b8fc420f
data/README.md CHANGED
@@ -78,6 +78,8 @@ end
78
78
 
79
79
  To learn more about sampling transactions, please visit the [official documentation](https://docs.sentry.io/platforms/ruby/configuration/sampling/#configuring-the-transaction-sample-rate).
80
80
 
81
+ ### [Migration Guide](https://docs.sentry.io/platforms/ruby/migration/)
82
+
81
83
  ### Integrations
82
84
 
83
85
  - [Rack](https://docs.sentry.io/platforms/ruby/guides/rack/)
@@ -8,7 +8,9 @@ module Sentry
8
8
  class BackgroundWorker
9
9
  include LoggingHelper
10
10
 
11
- attr_reader :max_queue, :number_of_threads, :logger
11
+ attr_reader :max_queue, :number_of_threads
12
+ # @deprecated Use Sentry.logger to retrieve the current logger instead.
13
+ attr_reader :logger
12
14
  attr_accessor :shutdown_timeout
13
15
 
14
16
  def initialize(configuration)
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ## Inspired by Rails' and Airbrake's backtrace parsers.
4
-
5
3
  module Sentry
6
- # Front end to parsing the backtrace for each notice
7
4
  # @api private
8
5
  class Backtrace
9
6
  # Handles backtrace parsing line by line
@@ -4,9 +4,25 @@ module Sentry
4
4
  class Breadcrumb
5
5
  DATA_SERIALIZATION_ERROR_MESSAGE = "[data were removed due to serialization issues]"
6
6
 
7
- attr_accessor :category, :data, :level, :timestamp, :type
7
+ # @return [String, nil]
8
+ attr_accessor :category
9
+ # @return [Hash, nil]
10
+ attr_accessor :data
11
+ # @return [String, nil]
12
+ attr_accessor :level
13
+ # @return [Time, Integer, nil]
14
+ attr_accessor :timestamp
15
+ # @return [String, nil]
16
+ attr_accessor :type
17
+ # @return [String, nil]
8
18
  attr_reader :message
9
19
 
20
+ # @param category [String, nil]
21
+ # @param data [Hash, nil]
22
+ # @param message [String, nil]
23
+ # @param timestamp [Time, Integer, nil]
24
+ # @param level [String, nil]
25
+ # @param type [String, nil]
10
26
  def initialize(category: nil, data: nil, message: nil, timestamp: nil, level: nil, type: nil)
11
27
  @category = category
12
28
  @data = data || {}
@@ -16,6 +32,7 @@ module Sentry
16
32
  self.message = message
17
33
  end
18
34
 
35
+ # @return [Hash]
19
36
  def to_hash
20
37
  {
21
38
  category: @category,
@@ -27,8 +44,10 @@ module Sentry
27
44
  }
28
45
  end
29
46
 
30
- def message=(msg)
31
- @message = (msg || "").byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES)
47
+ # @param message [String]
48
+ # @return [void]
49
+ def message=(message)
50
+ @message = (message || "").byteslice(0..Event::MAX_MESSAGE_SIZE_IN_BYTES)
32
51
  end
33
52
 
34
53
  private
@@ -7,40 +7,54 @@ module Sentry
7
7
  DEFAULT_SIZE = 100
8
8
  include Enumerable
9
9
 
10
+ # @return [Array]
10
11
  attr_accessor :buffer
11
12
 
13
+ # @param size [Integer, nil] If it's not provided, it'll fallback to DEFAULT_SIZE
12
14
  def initialize(size = nil)
13
15
  @buffer = Array.new(size || DEFAULT_SIZE)
14
16
  end
15
17
 
18
+ # @param crumb [Breadcrumb]
19
+ # @return [void]
16
20
  def record(crumb)
17
21
  yield(crumb) if block_given?
18
22
  @buffer.slice!(0)
19
23
  @buffer << crumb
20
24
  end
21
25
 
26
+ # @return [Array]
22
27
  def members
23
28
  @buffer.compact
24
29
  end
25
30
 
31
+ # Returns the last breadcrumb stored in the buffer. If the buffer it's empty, it returns nil.
32
+ # @return [Breadcrumb, nil]
26
33
  def peek
27
34
  members.last
28
35
  end
29
36
 
37
+ # Iterates through all breadcrumbs.
38
+ # @param block [Proc]
39
+ # @yieldparam crumb [Breadcrumb]
40
+ # @return [Array]
30
41
  def each(&block)
31
42
  members.each(&block)
32
43
  end
33
44
 
45
+ # @return [Boolean]
34
46
  def empty?
35
47
  members.none?
36
48
  end
37
49
 
50
+ # @return [Hash]
38
51
  def to_hash
39
52
  {
40
53
  values: members.map(&:to_hash)
41
54
  }
42
55
  end
43
56
 
57
+ # @return [BreadcrumbBuffer]
44
58
  def dup
45
59
  copy = super
46
60
  copy.buffer = buffer.deep_dup
data/lib/sentry/client.rb CHANGED
@@ -6,8 +6,17 @@ module Sentry
6
6
  class Client
7
7
  include LoggingHelper
8
8
 
9
- attr_reader :transport, :configuration, :logger
9
+ # The Transport object that'll send events for the client.
10
+ # @return [Transport]
11
+ attr_reader :transport
10
12
 
13
+ # @!macro configuration
14
+ attr_reader :configuration
15
+
16
+ # @deprecated Use Sentry.logger to retrieve the current logger instead.
17
+ attr_reader :logger
18
+
19
+ # @param configuration [Configuration]
11
20
  def initialize(configuration)
12
21
  @configuration = configuration
13
22
  @logger = configuration.logger
@@ -25,6 +34,11 @@ module Sentry
25
34
  end
26
35
  end
27
36
 
37
+ # Applies the given scope's data to the event and sends it to Sentry.
38
+ # @param event [Event] the event to be sent.
39
+ # @param scope [Scope] the scope with contextual data that'll be applied to the event before it's sent.
40
+ # @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
41
+ # @return [Event, nil]
28
42
  def capture_event(event, scope, hint = {})
29
43
  return unless configuration.sending_allowed?
30
44
 
@@ -57,9 +71,14 @@ module Sentry
57
71
  nil
58
72
  end
59
73
 
74
+ # Initializes an Event object with the given exception. Returns `nil` if the exception's class is excluded from reporting.
75
+ # @param exception [Exception] the exception to be reported.
76
+ # @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
77
+ # @return [Event, nil]
60
78
  def event_from_exception(exception, hint = {})
79
+ return unless @configuration.sending_allowed? && @configuration.exception_class_allowed?(exception)
80
+
61
81
  integration_meta = Sentry.integrations[hint[:integration]]
62
- return unless @configuration.exception_class_allowed?(exception)
63
82
 
64
83
  Event.new(configuration: configuration, integration_meta: integration_meta).tap do |event|
65
84
  event.add_exception_interface(exception)
@@ -67,13 +86,22 @@ module Sentry
67
86
  end
68
87
  end
69
88
 
89
+ # Initializes an Event object with the given message.
90
+ # @param message [String] the message to be reported.
91
+ # @param hint [Hash] the hint data that'll be passed to `before_send` callback and the scope's event processors.
92
+ # @return [Event]
70
93
  def event_from_message(message, hint = {}, backtrace: nil)
94
+ return unless @configuration.sending_allowed?
95
+
71
96
  integration_meta = Sentry.integrations[hint[:integration]]
72
97
  event = Event.new(configuration: configuration, integration_meta: integration_meta, message: message)
73
98
  event.add_threads_interface(backtrace: backtrace || caller)
74
99
  event
75
100
  end
76
101
 
102
+ # Initializes an Event object with the given Transaction object.
103
+ # @param transaction [Transaction] the transaction to be recorded.
104
+ # @return [TransactionEvent]
77
105
  def event_from_transaction(transaction)
78
106
  TransactionEvent.new(configuration: configuration).tap do |event|
79
107
  event.transaction = transaction.name
@@ -86,6 +114,7 @@ module Sentry
86
114
  end
87
115
  end
88
116
 
117
+ # @!macro send_event
89
118
  def send_event(event, hint = nil)
90
119
  event_type = event.is_a?(Event) ? event.type : event["type"]
91
120
 
@@ -112,6 +141,10 @@ module Sentry
112
141
  raise
113
142
  end
114
143
 
144
+ # Generates a Sentry trace for distribted tracing from the given Span.
145
+ # Returns `nil` if `config.propagate_traces` is `false`.
146
+ # @param span [Span] the span to generate trace from.
147
+ # @return [String, nil]
115
148
  def generate_sentry_trace(span)
116
149
  return unless configuration.propagate_traces
117
150
 
@@ -46,7 +46,7 @@ module Sentry
46
46
  # Rails.backtrace_cleaner.clean(backtrace)
47
47
  # end
48
48
  #
49
- # @return [Proc]
49
+ # @return [Proc, nil]
50
50
  attr_accessor :backtrace_cleanup_callback
51
51
 
52
52
  # Optional Proc, called before adding the breadcrumb to the current scope
@@ -127,8 +127,9 @@ module Sentry
127
127
  alias inspect_exception_causes_for_exclusion? inspect_exception_causes_for_exclusion
128
128
 
129
129
  # You may provide your own LineCache for matching paths with source files.
130
- # This may be useful if you need to get source code from places other than
131
- # the disk. See Sentry::LineCache for the required interface you must implement.
130
+ # This may be useful if you need to get source code from places other than the disk.
131
+ # @see LineCache
132
+ # @return [LineCache]
132
133
  attr_accessor :linecache
133
134
 
134
135
  # Logger used by Sentry. In Rails, this is the Rails logger, otherwise
data/lib/sentry/event.rb CHANGED
@@ -10,31 +10,40 @@ require 'sentry/utils/custom_inspection'
10
10
 
11
11
  module Sentry
12
12
  class Event
13
+ # These are readable attributes.
13
14
  SERIALIZEABLE_ATTRIBUTES = %i(
14
15
  event_id level timestamp
15
16
  release environment server_name modules
16
17
  message user tags contexts extra
17
- fingerprint breadcrumbs backtrace transaction
18
+ fingerprint breadcrumbs transaction
18
19
  platform sdk type
19
20
  )
20
21
 
22
+ # These are writable attributes.
21
23
  WRITER_ATTRIBUTES = SERIALIZEABLE_ATTRIBUTES - %i(type timestamp level)
22
24
 
23
25
  MAX_MESSAGE_SIZE_IN_BYTES = 1024 * 8
24
26
 
25
- SKIP_INSPECTION_ATTRIBUTES = [:@configuration, :@modules, :@backtrace]
27
+ SKIP_INSPECTION_ATTRIBUTES = [:@modules, :@stacktrace_builder, :@send_default_pii, :@trusted_proxies, :@rack_env_whitelist]
26
28
 
27
29
  include CustomInspection
28
30
 
29
31
  attr_writer(*WRITER_ATTRIBUTES)
30
32
  attr_reader(*SERIALIZEABLE_ATTRIBUTES)
31
33
 
32
- attr_reader :configuration, :request, :exception, :threads
34
+ # @return [RequestInterface]
35
+ attr_reader :request
33
36
 
34
- def initialize(configuration:, integration_meta: nil, message: nil)
35
- # this needs to go first because some setters rely on configuration
36
- @configuration = configuration
37
+ # @return [ExceptionInterface]
38
+ attr_reader :exception
39
+
40
+ # @return [ThreadsInterface]
41
+ attr_reader :threads
37
42
 
43
+ # @param configuration [Configuration]
44
+ # @param integration_meta [Hash, nil]
45
+ # @param message [String, nil]
46
+ def initialize(configuration:, integration_meta: nil, message: nil)
38
47
  # Set some simple default values
39
48
  @event_id = SecureRandom.uuid.delete("-")
40
49
  @timestamp = Sentry.utc_now.iso8601
@@ -48,17 +57,25 @@ module Sentry
48
57
 
49
58
  @fingerprint = []
50
59
 
60
+ # configuration data that's directly used by events
51
61
  @server_name = configuration.server_name
52
62
  @environment = configuration.environment
53
63
  @release = configuration.release
54
64
  @modules = configuration.gem_specs if configuration.send_modules
55
65
 
66
+ # configuration options to help events process data
67
+ @send_default_pii = configuration.send_default_pii
68
+ @trusted_proxies = configuration.trusted_proxies
69
+ @stacktrace_builder = configuration.stacktrace_builder
70
+ @rack_env_whitelist = configuration.rack_env_whitelist
71
+
56
72
  @message = (message || "").byteslice(0..MAX_MESSAGE_SIZE_IN_BYTES)
57
73
 
58
74
  self.level = :error
59
75
  end
60
76
 
61
77
  class << self
78
+ # @!visibility private
62
79
  def get_log_message(event_hash)
63
80
  message = event_hash[:message] || event_hash['message']
64
81
 
@@ -75,6 +92,7 @@ module Sentry
75
92
  '<no message value>'
76
93
  end
77
94
 
95
+ # @!visibility private
78
96
  def get_message_from_exception(event_hash)
79
97
  if exception = event_hash.dig(:exception, :values, 0)
80
98
  "#{exception[:type]}: #{exception[:value]}"
@@ -84,21 +102,35 @@ module Sentry
84
102
  end
85
103
  end
86
104
 
105
+ # @deprecated This method will be removed in v5.0.0. Please just use Sentry.configuration
106
+ # @return [Configuration]
107
+ def configuration
108
+ Sentry.configuration
109
+ end
110
+
111
+ # Sets the event's timestamp.
112
+ # @param time [Time, Float]
113
+ # @return [void]
87
114
  def timestamp=(time)
88
115
  @timestamp = time.is_a?(Time) ? time.to_f : time
89
116
  end
90
117
 
91
- def level=(new_level) # needed to meet the Sentry spec
92
- @level = new_level.to_s == "warn" ? :warning : new_level
118
+ # Sets the event's level.
119
+ # @param level [String, Symbol]
120
+ # @return [void]
121
+ def level=(level) # needed to meet the Sentry spec
122
+ @level = level.to_s == "warn" ? :warning : level
93
123
  end
94
124
 
125
+ # Sets the event's request environment data with RequestInterface.
126
+ # @see RequestInterface
127
+ # @param env [Hash]
128
+ # @return [void]
95
129
  def rack_env=(env)
96
130
  unless request || env.empty?
97
- env = env.dup
98
-
99
131
  add_request_interface(env)
100
132
 
101
- if configuration.send_default_pii
133
+ if @send_default_pii
102
134
  user[:ip_address] = calculate_real_ip_from_rack(env)
103
135
  end
104
136
 
@@ -108,6 +140,7 @@ module Sentry
108
140
  end
109
141
  end
110
142
 
143
+ # @return [Hash]
111
144
  def to_hash
112
145
  data = serialize_attributes
113
146
  data[:breadcrumbs] = breadcrumbs.to_hash if breadcrumbs
@@ -118,32 +151,35 @@ module Sentry
118
151
  data
119
152
  end
120
153
 
154
+ # @return [Hash]
121
155
  def to_json_compatible
122
156
  JSON.parse(JSON.generate(to_hash))
123
157
  end
124
158
 
125
- def add_request_interface(env)
126
- @request = Sentry::RequestInterface.build(env: env)
127
- end
128
-
159
+ # @!visibility private
129
160
  def add_threads_interface(backtrace: nil, **options)
130
161
  @threads = ThreadsInterface.build(
131
162
  backtrace: backtrace,
132
- stacktrace_builder: configuration.stacktrace_builder,
163
+ stacktrace_builder: @stacktrace_builder,
133
164
  **options
134
165
  )
135
166
  end
136
167
 
168
+ # @!visibility private
137
169
  def add_exception_interface(exception)
138
170
  if exception.respond_to?(:sentry_context)
139
171
  @extra.merge!(exception.sentry_context)
140
172
  end
141
173
 
142
- @exception = Sentry::ExceptionInterface.build(exception: exception, stacktrace_builder: configuration.stacktrace_builder)
174
+ @exception = Sentry::ExceptionInterface.build(exception: exception, stacktrace_builder: @stacktrace_builder)
143
175
  end
144
176
 
145
177
  private
146
178
 
179
+ def add_request_interface(env)
180
+ @request = Sentry::RequestInterface.new(env: env, send_default_pii: @send_default_pii, rack_env_whitelist: @rack_env_whitelist)
181
+ end
182
+
147
183
  def serialize_attributes
148
184
  self.class::SERIALIZEABLE_ATTRIBUTES.each_with_object({}) do |att, memo|
149
185
  if value = public_send(att)
@@ -160,7 +196,7 @@ module Sentry
160
196
  :client_ip => env["HTTP_CLIENT_IP"],
161
197
  :real_ip => env["HTTP_X_REAL_IP"],
162
198
  :forwarded_for => env["HTTP_X_FORWARDED_FOR"],
163
- :trusted_proxies => configuration.trusted_proxies
199
+ :trusted_proxies => @trusted_proxies
164
200
  ).calculate_ip
165
201
  end
166
202
  end
data/lib/sentry/hub.rb CHANGED
@@ -114,6 +114,9 @@ module Sentry
114
114
  options[:hint][:message] = message
115
115
  backtrace = options.delete(:backtrace)
116
116
  event = current_client.event_from_message(message, options[:hint], backtrace: backtrace)
117
+
118
+ return unless event
119
+
117
120
  capture_event(event, **options, &block)
118
121
  end
119
122
 
@@ -2,16 +2,7 @@
2
2
 
3
3
  module Sentry
4
4
  class Interface
5
- def self.inherited(klass)
6
- name = klass.name.split("::").last.downcase.gsub("interface", "")
7
- registered[name.to_sym] = klass
8
- super
9
- end
10
-
11
- def self.registered
12
- @@registered ||= {} # rubocop:disable Style/ClassVars
13
- end
14
-
5
+ # @return [Hash]
15
6
  def to_hash
16
7
  Hash[instance_variables.map { |name| [name[1..-1].to_sym, instance_variable_get(name)] }]
17
8
  end
@@ -2,16 +2,24 @@
2
2
 
3
3
  module Sentry
4
4
  class ExceptionInterface < Interface
5
- def initialize(values:)
6
- @values = values
5
+ # @param exceptions [Array<SingleExceptionInterface>]
6
+ def initialize(exceptions:)
7
+ @values = exceptions
7
8
  end
8
9
 
10
+ # @return [Hash]
9
11
  def to_hash
10
12
  data = super
11
13
  data[:values] = data[:values].map(&:to_hash) if data[:values]
12
14
  data
13
15
  end
14
16
 
17
+ # Builds ExceptionInterface with given exception and stacktrace_builder.
18
+ # @param exception [Exception]
19
+ # @param stacktrace_builder [StacktraceBuilder]
20
+ # @see SingleExceptionInterface#build_with_stacktrace
21
+ # @see SingleExceptionInterface#initialize
22
+ # @return [ExceptionInterface]
15
23
  def self.build(exception:, stacktrace_builder:)
16
24
  exceptions = Sentry::Utils::ExceptionCauseChain.exception_to_array(exception).reverse
17
25
  processed_backtrace_ids = Set.new
@@ -25,7 +33,7 @@ module Sentry
25
33
  end
26
34
  end
27
35
 
28
- new(values: exceptions)
36
+ new(exceptions: exceptions)
29
37
  end
30
38
  end
31
39
  end
@@ -15,29 +15,45 @@ module Sentry
15
15
  # https://github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py
16
16
  MAX_BODY_LIMIT = 4096 * 4
17
17
 
18
- attr_accessor :url, :method, :data, :query_string, :cookies, :headers, :env
18
+ # @return [String]
19
+ attr_accessor :url
19
20
 
20
- def self.build(env:)
21
- env = clean_env(env)
22
- request = ::Rack::Request.new(env)
23
- self.new(request: request)
24
- end
21
+ # @return [String]
22
+ attr_accessor :method
23
+
24
+ # @return [Hash]
25
+ attr_accessor :data
26
+
27
+ # @return [String]
28
+ attr_accessor :query_string
29
+
30
+ # @return [String]
31
+ attr_accessor :cookies
32
+
33
+ # @return [Hash]
34
+ attr_accessor :headers
25
35
 
26
- def self.clean_env(env)
27
- unless Sentry.configuration.send_default_pii
36
+ # @return [Hash]
37
+ attr_accessor :env
38
+
39
+ # @param env [Hash]
40
+ # @param send_default_pii [Boolean]
41
+ # @param rack_env_whitelist [Array]
42
+ # @see Configuration#send_default_pii
43
+ # @see Configuration#rack_env_whitelist
44
+ def initialize(env:, send_default_pii:, rack_env_whitelist:)
45
+ env = env.dup
46
+
47
+ unless send_default_pii
28
48
  # need to completely wipe out ip addresses
29
49
  RequestInterface::IP_HEADERS.each do |header|
30
50
  env.delete(header)
31
51
  end
32
52
  end
33
53
 
34
- env
35
- end
36
-
37
- def initialize(request:)
38
- env = request.env
54
+ request = ::Rack::Request.new(env)
39
55
 
40
- if Sentry.configuration.send_default_pii
56
+ if send_default_pii
41
57
  self.data = read_data_from(request)
42
58
  self.cookies = request.cookies
43
59
  self.query_string = request.query_string
@@ -47,7 +63,7 @@ module Sentry
47
63
  self.method = request.request_method
48
64
 
49
65
  self.headers = filter_and_format_headers(env)
50
- self.env = filter_and_format_env(env)
66
+ self.env = filter_and_format_env(env, rack_env_whitelist)
51
67
  end
52
68
 
53
69
  private
@@ -116,11 +132,11 @@ module Sentry
116
132
  key == 'HTTP_VERSION' && value == protocol_version
117
133
  end
118
134
 
119
- def filter_and_format_env(env)
120
- return env if Sentry.configuration.rack_env_whitelist.empty?
135
+ def filter_and_format_env(env, rack_env_whitelist)
136
+ return env if rack_env_whitelist.empty?
121
137
 
122
138
  env.select do |k, _v|
123
- Sentry.configuration.rack_env_whitelist.include? k.to_s
139
+ rack_env_whitelist.include? k.to_s
124
140
  end
125
141
  end
126
142
  end
@@ -2,16 +2,20 @@
2
2
 
3
3
  module Sentry
4
4
  class StacktraceInterface
5
+ # @return [<Array[Frame]>]
5
6
  attr_reader :frames
6
7
 
8
+ # @param frames [<Array[Frame]>]
7
9
  def initialize(frames:)
8
10
  @frames = frames
9
11
  end
10
12
 
13
+ # @return [Hash]
11
14
  def to_hash
12
15
  { frames: @frames.map(&:to_hash) }
13
16
  end
14
17
 
18
+ # @return [String]
15
19
  def inspect
16
20
  @frames.map(&:to_s)
17
21
  end
@@ -2,8 +2,31 @@
2
2
 
3
3
  module Sentry
4
4
  class StacktraceBuilder
5
- attr_reader :project_root, :app_dirs_pattern, :linecache, :context_lines, :backtrace_cleanup_callback
5
+ # @return [String]
6
+ attr_reader :project_root
6
7
 
8
+ # @return [Regexp, nil]
9
+ attr_reader :app_dirs_pattern
10
+
11
+ # @return [LineCache]
12
+ attr_reader :linecache
13
+
14
+ # @return [Integer, nil]
15
+ attr_reader :context_lines
16
+
17
+ # @return [Proc, nil]
18
+ attr_reader :backtrace_cleanup_callback
19
+
20
+ # @param project_root [String]
21
+ # @param app_dirs_pattern [Regexp, nil]
22
+ # @param linecache [LineCache]
23
+ # @param context_lines [Integer, nil]
24
+ # @param backtrace_cleanup_callback [Proc, nil]
25
+ # @see Configuration#project_root
26
+ # @see Configuration#app_dirs_pattern
27
+ # @see Configuration#linecache
28
+ # @see Configuration#context_lines
29
+ # @see Configuration#backtrace_cleanup_callback
7
30
  def initialize(project_root:, app_dirs_pattern:, linecache:, context_lines:, backtrace_cleanup_callback: nil)
8
31
  @project_root = project_root
9
32
  @app_dirs_pattern = app_dirs_pattern
@@ -12,17 +35,21 @@ module Sentry
12
35
  @backtrace_cleanup_callback = backtrace_cleanup_callback
13
36
  end
14
37
 
15
- # you can pass a block to customize/exclude frames:
38
+ # Generates a StacktraceInterface with the given backtrace.
39
+ # You can pass a block to customize/exclude frames:
16
40
  #
17
- # ```ruby
18
- # builder.build(backtrace) do |frame|
19
- # if frame.module.match?(/a_gem/)
20
- # nil
21
- # else
22
- # frame
41
+ # @example
42
+ # builder.build(backtrace) do |frame|
43
+ # if frame.module.match?(/a_gem/)
44
+ # nil
45
+ # else
46
+ # frame
47
+ # end
23
48
  # end
24
- # end
25
- # ```
49
+ # @param backtrace [Array<String>]
50
+ # @param frame_callback [Proc]
51
+ # @yieldparam frame [StacktraceInterface::Frame]
52
+ # @return [StacktraceInterface]
26
53
  def build(backtrace:, &frame_callback)
27
54
  parsed_lines = parse_backtrace_lines(backtrace).select(&:file)
28
55