airbrake-ruby 3.2.6 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/airbrake-ruby.rb +31 -138
- data/lib/airbrake-ruby/async_sender.rb +20 -8
- data/lib/airbrake-ruby/backtrace.rb +15 -13
- data/lib/airbrake-ruby/code_hunk.rb +2 -4
- data/lib/airbrake-ruby/config.rb +8 -38
- data/lib/airbrake-ruby/deploy_notifier.rb +4 -17
- data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +5 -4
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +6 -4
- data/lib/airbrake-ruby/filters/keys_blacklist.rb +0 -1
- data/lib/airbrake-ruby/filters/keys_filter.rb +4 -4
- data/lib/airbrake-ruby/filters/keys_whitelist.rb +0 -1
- data/lib/airbrake-ruby/loggable.rb +31 -0
- data/lib/airbrake-ruby/nested_exception.rb +2 -3
- data/lib/airbrake-ruby/notice.rb +6 -6
- data/lib/airbrake-ruby/notice_notifier.rb +11 -47
- data/lib/airbrake-ruby/performance_notifier.rb +6 -18
- data/lib/airbrake-ruby/response.rb +5 -2
- data/lib/airbrake-ruby/sync_sender.rb +8 -6
- data/lib/airbrake-ruby/version.rb +1 -1
- data/spec/airbrake_spec.rb +1 -143
- data/spec/async_sender_spec.rb +83 -90
- data/spec/backtrace_spec.rb +36 -47
- data/spec/code_hunk_spec.rb +12 -15
- data/spec/config_spec.rb +79 -96
- data/spec/deploy_notifier_spec.rb +3 -7
- data/spec/filter_chain_spec.rb +1 -3
- data/spec/filters/context_filter_spec.rb +1 -3
- data/spec/filters/dependency_filter_spec.rb +1 -3
- data/spec/filters/exception_attributes_filter_spec.rb +1 -14
- data/spec/filters/gem_root_filter_spec.rb +1 -4
- data/spec/filters/git_last_checkout_filter_spec.rb +3 -5
- data/spec/filters/git_revision_filter_spec.rb +1 -3
- data/spec/filters/keys_blacklist_spec.rb +14 -25
- data/spec/filters/keys_whitelist_spec.rb +14 -25
- data/spec/filters/root_directory_filter_spec.rb +1 -4
- data/spec/filters/system_exit_filter_spec.rb +2 -2
- data/spec/filters/thread_filter_spec.rb +1 -3
- data/spec/nested_exception_spec.rb +3 -5
- data/spec/notice_notifier_spec.rb +23 -20
- data/spec/notice_notifier_spec/options_spec.rb +20 -25
- data/spec/notice_spec.rb +13 -12
- data/spec/performance_notifier_spec.rb +19 -31
- data/spec/response_spec.rb +23 -17
- data/spec/sync_sender_spec.rb +26 -33
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f02fa6e61f0c293426ab4b4c3347106dadba90a8
|
4
|
+
data.tar.gz: aab5dbba3ec59829fb95b4b3d6a24c67a38023d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d4c7e5134c8fb761a469bc082518b920b0de8a6e1845b3e1b574a71bc33fab56e1e51235434a65d2e68b1069e78e397a2438b0b48e885c33afba503962a929a
|
7
|
+
data.tar.gz: 01d60cea9501d88ca04b45c57a19d568e42a3bfb07e09ffbe23fb9a67e1dab02fc60c2bd1ab564aad164a40e28635a6fb47ec2d1baf5c8c2e13c4196e64eba99
|
data/lib/airbrake-ruby.rb
CHANGED
@@ -7,6 +7,7 @@ require 'socket'
|
|
7
7
|
require 'time'
|
8
8
|
|
9
9
|
require 'airbrake-ruby/version'
|
10
|
+
require 'airbrake-ruby/loggable'
|
10
11
|
require 'airbrake-ruby/config'
|
11
12
|
require 'airbrake-ruby/config/validator'
|
12
13
|
require 'airbrake-ruby/promise'
|
@@ -46,40 +47,22 @@ require 'airbrake-ruby/tdigest'
|
|
46
47
|
require 'airbrake-ruby/query'
|
47
48
|
require 'airbrake-ruby/request'
|
48
49
|
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
50
|
+
# Airbrake is a thin wrapper around instances of the notifier classes (such as
|
51
|
+
# notice, performance & deploy notifiers). It creates a way to access them via a
|
52
|
+
# consolidated global interface.
|
52
53
|
#
|
53
|
-
#
|
54
|
-
# differently. By default, every method is invoked in context of the default
|
55
|
-
# notifier. To use a different notifier, you need to {configure} it first and
|
56
|
-
# pass the notifier's name as the last argument of the method you're calling.
|
54
|
+
# Prior to using it, you must {configure} it.
|
57
55
|
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
# @example Configuring multiple notifiers and using them
|
61
|
-
# # Configure the default notifier.
|
56
|
+
# @example
|
62
57
|
# Airbrake.configure do |c|
|
63
58
|
# c.project_id = 113743
|
64
59
|
# c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
|
65
60
|
# end
|
66
61
|
#
|
67
|
-
# # Configure a named notifier.
|
68
|
-
# Airbrake.configure(:my_other_project) do |c|
|
69
|
-
# c.project_id = 224854
|
70
|
-
# c.project_key = '91ac5e4a37496026c6837f63276ed2b6'
|
71
|
-
# end
|
72
|
-
#
|
73
|
-
# # Send an exception via the default notifier.
|
74
62
|
# Airbrake.notify('Oops!')
|
75
63
|
#
|
76
|
-
# # Send an exception via other configured notifier.
|
77
|
-
# params = {}
|
78
|
-
# Airbrake[:my_other_project].notify('Oops', params)
|
79
|
-
#
|
80
|
-
# @see Airbrake::NoticeNotifier
|
81
64
|
# @since v1.0.0
|
82
|
-
#
|
65
|
+
# @api public
|
83
66
|
module Airbrake
|
84
67
|
# The general error that this library uses when it wants to raise.
|
85
68
|
Error = Class.new(StandardError)
|
@@ -127,14 +110,6 @@ module Airbrake
|
|
127
110
|
def merge_context(_context); end
|
128
111
|
end
|
129
112
|
|
130
|
-
# @deprecated Use {Airbrake::NoticeNotifier} instead
|
131
|
-
Notifier = NoticeNotifier
|
132
|
-
deprecate_constant(:Notifier) if respond_to?(:deprecate_constant)
|
133
|
-
|
134
|
-
# @deprecated Use {Airbrake::NilNoticeNotifier} instead
|
135
|
-
NilNotifier = NilNoticeNotifier
|
136
|
-
deprecate_constant(:NilNotifier) if respond_to?(:deprecate_constant)
|
137
|
-
|
138
113
|
# NilPerformanceNotifier is a no-op notifier, which mimics
|
139
114
|
# {Airbrake::PerformanceNotifier} and serves only the purpose of making the
|
140
115
|
# library API easier to use.
|
@@ -160,75 +135,23 @@ module Airbrake
|
|
160
135
|
#
|
161
136
|
# @since v3.2.0
|
162
137
|
class NilDeployNotifier
|
163
|
-
# @see Airbrake.
|
138
|
+
# @see Airbrake.notify_deploy
|
164
139
|
def notify(_deploy_info); end
|
165
140
|
end
|
166
141
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
@notice_notifiers = Hash.new(NilNoticeNotifier.new)
|
171
|
-
|
172
|
-
# A Hash that holds all performance notifiers. The keys of the Hash are
|
173
|
-
# notifier names, the values are {Airbrake::PerformanceNotifier} instances. If
|
174
|
-
# a notifier is not assigned to the hash, then it returns a null object
|
175
|
-
# (NilPerformanceNotifier).
|
176
|
-
@performance_notifiers = Hash.new(NilPerformanceNotifier.new)
|
177
|
-
|
178
|
-
# A Hash that holds all deploy notifiers. The keys of the Hash are notifier
|
179
|
-
# names, the values are {Airbrake::DeployNotifier} instances. If a deploy
|
180
|
-
# notifier is not assigned to the hash, then it returns a null object
|
181
|
-
# (NilDeployNotifier).
|
182
|
-
@deploy_notifiers = Hash.new(NilDeployNotifier.new)
|
142
|
+
@notice_notifier = NilNoticeNotifier.new
|
143
|
+
@performance_notifier = NilPerformanceNotifier.new
|
144
|
+
@deploy_notifier = NilDeployNotifier.new
|
183
145
|
|
184
146
|
class << self
|
185
|
-
# Retrieves configured notifiers.
|
186
|
-
#
|
187
|
-
# @example
|
188
|
-
# Airbrake[:my_notifier].notify('oops')
|
189
|
-
#
|
190
|
-
# @param [Symbol] notifier_name the name of the notice notifier you want to
|
191
|
-
# use
|
192
|
-
# @return [Airbrake::NoticeNotifier, NilClass]
|
193
|
-
# @since v1.8.0
|
194
|
-
def [](notifier_name)
|
195
|
-
loc = caller_locations(1..1).first
|
196
|
-
signature = "#{self}##{__method__}"
|
197
|
-
warn(
|
198
|
-
"#{loc.path}:#{loc.lineno}: warning: #{signature} is deprecated. It " \
|
199
|
-
"will be removed from airbrake-ruby v4 altogether."
|
200
|
-
)
|
201
|
-
|
202
|
-
@notice_notifiers[notifier_name]
|
203
|
-
end
|
204
|
-
|
205
|
-
# @return [Hash{Symbol=>Array<Object>}] a Hash with all configured notifiers
|
206
|
-
# (notice, performance, deploy)
|
207
|
-
# @since v3.2.0
|
208
|
-
def notifiers
|
209
|
-
loc = caller_locations(1..1).first
|
210
|
-
signature = "#{self}##{__method__}"
|
211
|
-
warn(
|
212
|
-
"#{loc.path}:#{loc.lineno}: warning: #{signature} is deprecated. It " \
|
213
|
-
"will be removed from airbrake-ruby v4 altogether."
|
214
|
-
)
|
215
|
-
|
216
|
-
{
|
217
|
-
notice: @notice_notifiers,
|
218
|
-
performance: @performance_notifiers,
|
219
|
-
deploy: @deploy_notifiers
|
220
|
-
}
|
221
|
-
end
|
222
|
-
|
223
147
|
# Configures the Airbrake notifier.
|
224
148
|
#
|
225
|
-
# @example
|
149
|
+
# @example
|
226
150
|
# Airbrake.configure do |c|
|
227
151
|
# c.project_id = 113743
|
228
152
|
# c.project_key = 'fd04e13d806a90f96614ad8e529b2822'
|
229
153
|
# end
|
230
154
|
#
|
231
|
-
# @param [Symbol] notifier_name the name to be associated with the notifier
|
232
155
|
# @yield [config] The configuration object
|
233
156
|
# @yieldparam config [Airbrake::Config]
|
234
157
|
# @return [void]
|
@@ -236,41 +159,23 @@ module Airbrake
|
|
236
159
|
# existing notifier
|
237
160
|
# @raise [Airbrake::Error] when either +project_id+ or +project_key+
|
238
161
|
# is missing (or both)
|
239
|
-
# @note There's no way to reconfigure a notifier
|
240
162
|
# @note There's no way to read config values outside of this library
|
241
|
-
def configure
|
242
|
-
|
243
|
-
loc = caller_locations(1..1).first
|
244
|
-
warn(
|
245
|
-
"#{loc.path}:#{loc.lineno}: warning: configuring a notifier with a " \
|
246
|
-
"custom name is deprecated. This feature will be removed from " \
|
247
|
-
"airbrake-ruby v4 altogether."
|
248
|
-
)
|
249
|
-
end
|
250
|
-
|
251
|
-
yield config = Airbrake::Config.new
|
252
|
-
|
253
|
-
if @notice_notifiers.key?(notifier_name)
|
254
|
-
raise Airbrake::Error,
|
255
|
-
"the '#{notifier_name}' notifier was already configured"
|
256
|
-
end
|
163
|
+
def configure
|
164
|
+
yield config = Airbrake::Config.instance
|
257
165
|
|
258
166
|
raise Airbrake::Error, config.validation_error_message unless config.valid?
|
259
167
|
|
260
|
-
|
261
|
-
# https://github.com/airbrake/airbrake-ruby/issues/406
|
262
|
-
# Stop passing perf_notifier to NoticeNotifier as soon as possible.
|
263
|
-
perf_notifier = PerformanceNotifier.new(config)
|
264
|
-
@performance_notifiers[notifier_name] = perf_notifier
|
265
|
-
@notice_notifiers[notifier_name] = NoticeNotifier.new(config, perf_notifier)
|
168
|
+
Airbrake::Loggable.instance = Airbrake::Config.instance
|
266
169
|
|
267
|
-
@
|
170
|
+
@performance_notifier = PerformanceNotifier.new
|
171
|
+
@notice_notifier = NoticeNotifier.new
|
172
|
+
@deploy_notifier = DeployNotifier.new
|
268
173
|
end
|
269
174
|
|
270
175
|
# @return [Boolean] true if the notifier was configured, false otherwise
|
271
176
|
# @since v2.3.0
|
272
177
|
def configured?
|
273
|
-
@
|
178
|
+
@notice_notifier.configured?
|
274
179
|
end
|
275
180
|
|
276
181
|
# Sends an exception to Airbrake asynchronously.
|
@@ -295,7 +200,7 @@ module Airbrake
|
|
295
200
|
# @return [Airbrake::Promise]
|
296
201
|
# @see .notify_sync
|
297
202
|
def notify(exception, params = {}, &block)
|
298
|
-
@
|
203
|
+
@notice_notifier.notify(exception, params, &block)
|
299
204
|
end
|
300
205
|
|
301
206
|
# Sends an exception to Airbrake synchronously.
|
@@ -315,7 +220,7 @@ module Airbrake
|
|
315
220
|
# @return [Hash{String=>String}] the reponse from the server
|
316
221
|
# @see .notify
|
317
222
|
def notify_sync(exception, params = {}, &block)
|
318
|
-
@
|
223
|
+
@notice_notifier.notify_sync(exception, params, &block)
|
319
224
|
end
|
320
225
|
|
321
226
|
# Runs a callback before {.notify} or {.notify_sync} kicks in. This is
|
@@ -343,7 +248,7 @@ module Airbrake
|
|
343
248
|
# @yieldreturn [void]
|
344
249
|
# @return [void]
|
345
250
|
def add_filter(filter = nil, &block)
|
346
|
-
@
|
251
|
+
@notice_notifier.add_filter(filter, &block)
|
347
252
|
end
|
348
253
|
|
349
254
|
# Deletes a filter added via {Airbrake#add_filter}.
|
@@ -360,7 +265,7 @@ module Airbrake
|
|
360
265
|
# @since v3.1.0
|
361
266
|
# @note This method cannot delete filters assigned via the Proc form.
|
362
267
|
def delete_filter(filter_class)
|
363
|
-
@
|
268
|
+
@notice_notifier.delete_filter(filter_class)
|
364
269
|
end
|
365
270
|
|
366
271
|
# Builds an Airbrake notice. This is useful, if you want to add or modify a
|
@@ -378,7 +283,7 @@ module Airbrake
|
|
378
283
|
# @return [Airbrake::Notice] the notice built with help of the given
|
379
284
|
# arguments
|
380
285
|
def build_notice(exception, params = {})
|
381
|
-
@
|
286
|
+
@notice_notifier.build_notice(exception, params)
|
382
287
|
end
|
383
288
|
|
384
289
|
# Makes the notice notifier a no-op, which means you cannot use the
|
@@ -391,7 +296,7 @@ module Airbrake
|
|
391
296
|
#
|
392
297
|
# @return [void]
|
393
298
|
def close
|
394
|
-
@
|
299
|
+
@notice_notifier.close
|
395
300
|
end
|
396
301
|
|
397
302
|
# Pings the Airbrake Deploy API endpoint about the occurred deploy.
|
@@ -404,18 +309,7 @@ module Airbrake
|
|
404
309
|
# @option deploy_info [Symbol] :version
|
405
310
|
# @return [void]
|
406
311
|
def notify_deploy(deploy_info)
|
407
|
-
@
|
408
|
-
end
|
409
|
-
|
410
|
-
# @see notify_deploy
|
411
|
-
def create_deploy(deploy_info)
|
412
|
-
loc = caller_locations(1..1).first
|
413
|
-
signature = "#{self}##{__method__}"
|
414
|
-
warn(
|
415
|
-
"#{loc.path}:#{loc.lineno}: warning: #{signature} is deprecated. Call " \
|
416
|
-
"#{self}#notify_deploy instead"
|
417
|
-
)
|
418
|
-
notify_deploy(deploy_info)
|
312
|
+
@deploy_notifier.notify(deploy_info)
|
419
313
|
end
|
420
314
|
|
421
315
|
# Merges +context+ with the current context.
|
@@ -463,7 +357,7 @@ module Airbrake
|
|
463
357
|
# @param [Hash{Symbol=>Object}] context
|
464
358
|
# @return [void]
|
465
359
|
def merge_context(context)
|
466
|
-
@
|
360
|
+
@notice_notifier.merge_context(context)
|
467
361
|
end
|
468
362
|
|
469
363
|
# Increments request statistics of a certain +route+ that was invoked on
|
@@ -502,7 +396,7 @@ module Airbrake
|
|
502
396
|
# @since v3.0.0
|
503
397
|
# @see Airbrake::PerformanceNotifier#notify
|
504
398
|
def notify_request(request_info)
|
505
|
-
@
|
399
|
+
@performance_notifier.notify(Request.new(request_info))
|
506
400
|
end
|
507
401
|
|
508
402
|
# Increments SQL statistics of a certain +query+ that was invoked on
|
@@ -534,7 +428,7 @@ module Airbrake
|
|
534
428
|
# @since v3.2.0
|
535
429
|
# @see Airbrake::PerformanceNotifier#notify
|
536
430
|
def notify_query(query_info)
|
537
|
-
@
|
431
|
+
@performance_notifier.notify(Query.new(query_info))
|
538
432
|
end
|
539
433
|
|
540
434
|
# Runs a callback before {.notify_request} or {.notify_query} kicks in. This
|
@@ -569,7 +463,7 @@ module Airbrake
|
|
569
463
|
# @since v3.2.0
|
570
464
|
# @see Airbrake::PerformanceNotifier#add_filter
|
571
465
|
def add_performance_filter(filter = nil, &block)
|
572
|
-
@
|
466
|
+
@performance_notifier.add_filter(filter, &block)
|
573
467
|
end
|
574
468
|
|
575
469
|
# Deletes a filter added via {Airbrake#add_performance_filter}.
|
@@ -587,8 +481,7 @@ module Airbrake
|
|
587
481
|
# @note This method cannot delete filters assigned via the Proc form.
|
588
482
|
# @see Airbrake::PerformanceNotifier#delete_filter
|
589
483
|
def delete_performance_filter(filter_class)
|
590
|
-
@
|
484
|
+
@performance_notifier.delete_filter(filter_class)
|
591
485
|
end
|
592
486
|
end
|
593
487
|
end
|
594
|
-
# rubocop:enable Metrics/ModuleLength
|
@@ -7,11 +7,23 @@ module Airbrake
|
|
7
7
|
# @api private
|
8
8
|
# @since v1.0.0
|
9
9
|
class AsyncSender
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
include Loggable
|
11
|
+
|
12
|
+
# @return [ThreadGroup] the list of workers
|
13
|
+
# @note This is exposed for eaiser unit testing
|
14
|
+
# @since v4.0.0
|
15
|
+
attr_reader :workers
|
16
|
+
|
17
|
+
# @return [Array<[Airbrake::Notice,Airbrake::Promise]>] the list of unsent
|
18
|
+
# payload
|
19
|
+
# @note This is exposed for eaiser unit testing
|
20
|
+
# @since v4.0.0
|
21
|
+
attr_reader :unsent
|
22
|
+
|
23
|
+
def initialize
|
24
|
+
@config = Airbrake::Config.instance
|
25
|
+
@unsent = SizedQueue.new(Airbrake::Config.instance.queue_size)
|
26
|
+
@sender = SyncSender.new
|
15
27
|
@closed = false
|
16
28
|
@workers = ThreadGroup.new
|
17
29
|
@mutex = Mutex.new
|
@@ -41,7 +53,7 @@ module Airbrake
|
|
41
53
|
|
42
54
|
unless @unsent.empty?
|
43
55
|
msg = "#{LOG_LABEL} waiting to send #{@unsent.size} unsent notice(s)..."
|
44
|
-
|
56
|
+
logger.debug(msg + ' (Ctrl-C to abort)')
|
45
57
|
end
|
46
58
|
|
47
59
|
@config.workers.times { @unsent << [:stop, Airbrake::Promise.new] }
|
@@ -50,7 +62,7 @@ module Airbrake
|
|
50
62
|
end
|
51
63
|
|
52
64
|
threads.each(&:join)
|
53
|
-
|
65
|
+
logger.debug("#{LOG_LABEL} closed")
|
54
66
|
end
|
55
67
|
|
56
68
|
# Checks whether the sender is closed and thus usable.
|
@@ -107,7 +119,7 @@ module Airbrake
|
|
107
119
|
backtrace = notice[:errors][0][:backtrace].map do |line|
|
108
120
|
"#{line[:file]}:#{line[:line]} in `#{line[:function]}'"
|
109
121
|
end
|
110
|
-
|
122
|
+
logger.error(
|
111
123
|
"#{LOG_LABEL} AsyncSender has reached its capacity of " \
|
112
124
|
"#{@unsent.max} and the following notice will not be delivered " \
|
113
125
|
"Error: #{notice[:errors][0][:type]} - #{notice[:errors][0][:message]}\n" \
|
@@ -7,7 +7,7 @@ module Airbrake
|
|
7
7
|
# begin
|
8
8
|
# raise 'Oops!'
|
9
9
|
# rescue
|
10
|
-
# Backtrace.parse(
|
10
|
+
# Backtrace.parse($!)
|
11
11
|
# end
|
12
12
|
#
|
13
13
|
# @api private
|
@@ -93,9 +93,9 @@ module Airbrake
|
|
93
93
|
# @param [Exception] exception The exception, which contains a backtrace to
|
94
94
|
# parse
|
95
95
|
# @return [Array<Hash{Symbol=>String,Integer}>] the parsed backtrace
|
96
|
-
def self.parse(
|
96
|
+
def self.parse(exception)
|
97
97
|
return [] if exception.backtrace.nil? || exception.backtrace.none?
|
98
|
-
parse_backtrace(
|
98
|
+
parse_backtrace(exception)
|
99
99
|
end
|
100
100
|
|
101
101
|
# Checks whether the given exception was generated by JRuby's VM.
|
@@ -114,6 +114,8 @@ module Airbrake
|
|
114
114
|
end
|
115
115
|
|
116
116
|
class << self
|
117
|
+
include Loggable
|
118
|
+
|
117
119
|
private
|
118
120
|
|
119
121
|
def best_regexp_for(exception)
|
@@ -140,7 +142,7 @@ module Airbrake
|
|
140
142
|
false
|
141
143
|
end
|
142
144
|
|
143
|
-
def stack_frame(
|
145
|
+
def stack_frame(regexp, stackframe)
|
144
146
|
if (match = match_frame(regexp, stackframe))
|
145
147
|
return {
|
146
148
|
file: match[:file],
|
@@ -149,7 +151,7 @@ module Airbrake
|
|
149
151
|
}
|
150
152
|
end
|
151
153
|
|
152
|
-
|
154
|
+
logger.error(
|
153
155
|
"can't parse '#{stackframe}' (please file an issue so we can fix " \
|
154
156
|
"it: https://github.com/airbrake/airbrake-ruby/issues/new)"
|
155
157
|
)
|
@@ -163,26 +165,26 @@ module Airbrake
|
|
163
165
|
Patterns::GENERIC.match(stackframe)
|
164
166
|
end
|
165
167
|
|
166
|
-
def parse_backtrace(
|
168
|
+
def parse_backtrace(exception)
|
167
169
|
regexp = best_regexp_for(exception)
|
168
|
-
root_directory =
|
170
|
+
root_directory = Airbrake::Config.instance.root_directory.to_s
|
169
171
|
|
170
172
|
exception.backtrace.map.with_index do |stackframe, i|
|
171
|
-
frame = stack_frame(
|
172
|
-
next(frame) if !
|
173
|
+
frame = stack_frame(regexp, stackframe)
|
174
|
+
next(frame) if !Airbrake::Config.instance.code_hunks || frame[:file].nil?
|
173
175
|
|
174
176
|
if !root_directory.empty?
|
175
|
-
populate_code(
|
177
|
+
populate_code(frame) if frame_in_root?(frame, root_directory)
|
176
178
|
elsif i < CODE_FRAME_LIMIT
|
177
|
-
populate_code(
|
179
|
+
populate_code(frame)
|
178
180
|
end
|
179
181
|
|
180
182
|
frame
|
181
183
|
end
|
182
184
|
end
|
183
185
|
|
184
|
-
def populate_code(
|
185
|
-
code = Airbrake::CodeHunk.new
|
186
|
+
def populate_code(frame)
|
187
|
+
code = Airbrake::CodeHunk.new.get(frame[:file], frame[:line])
|
186
188
|
frame[:code] = code if code
|
187
189
|
end
|
188
190
|
|