bugsnag 6.20.0 → 6.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +110 -0
  3. data/VERSION +1 -1
  4. data/lib/bugsnag/breadcrumb_type.rb +14 -0
  5. data/lib/bugsnag/breadcrumbs/breadcrumb.rb +34 -1
  6. data/lib/bugsnag/breadcrumbs/breadcrumbs.rb +1 -0
  7. data/lib/bugsnag/breadcrumbs/on_breadcrumb_callback_list.rb +50 -0
  8. data/lib/bugsnag/cleaner.rb +31 -18
  9. data/lib/bugsnag/configuration.rb +243 -25
  10. data/lib/bugsnag/delivery/synchronous.rb +2 -2
  11. data/lib/bugsnag/delivery/thread_queue.rb +2 -2
  12. data/lib/bugsnag/endpoint_configuration.rb +11 -0
  13. data/lib/bugsnag/endpoint_validator.rb +80 -0
  14. data/lib/bugsnag/error.rb +25 -0
  15. data/lib/bugsnag/event.rb +7 -0
  16. data/lib/bugsnag/integrations/rack.rb +3 -3
  17. data/lib/bugsnag/integrations/rails/active_job.rb +102 -0
  18. data/lib/bugsnag/integrations/railtie.rb +43 -36
  19. data/lib/bugsnag/integrations/resque.rb +13 -3
  20. data/lib/bugsnag/middleware/active_job.rb +18 -0
  21. data/lib/bugsnag/middleware/delayed_job.rb +21 -2
  22. data/lib/bugsnag/middleware/exception_meta_data.rb +2 -0
  23. data/lib/bugsnag/middleware/rack_request.rb +84 -19
  24. data/lib/bugsnag/middleware/rails3_request.rb +2 -2
  25. data/lib/bugsnag/middleware/rake.rb +1 -1
  26. data/lib/bugsnag/middleware/session_data.rb +3 -1
  27. data/lib/bugsnag/middleware/sidekiq.rb +1 -1
  28. data/lib/bugsnag/middleware_stack.rb +6 -6
  29. data/lib/bugsnag/report.rb +166 -6
  30. data/lib/bugsnag/session_tracker.rb +52 -12
  31. data/lib/bugsnag/stacktrace.rb +10 -1
  32. data/lib/bugsnag/tasks/bugsnag.rake +1 -1
  33. data/lib/bugsnag/utility/duplicator.rb +124 -0
  34. data/lib/bugsnag/utility/metadata_delegate.rb +102 -0
  35. data/lib/bugsnag.rb +139 -7
  36. metadata +12 -2
@@ -34,16 +34,20 @@ module Bugsnag
34
34
  # Starts a new session, storing it on the current thread.
35
35
  #
36
36
  # This allows Bugsnag to track error rates for a release.
37
+ #
38
+ # @return [void]
37
39
  def start_session
38
- return unless Bugsnag.configuration.enable_sessions
40
+ return unless Bugsnag.configuration.enable_sessions && Bugsnag.configuration.should_notify_release_stage?
41
+
39
42
  start_delivery_thread
40
43
  start_time = Time.now().utc().strftime('%Y-%m-%dT%H:%M:00')
41
44
  new_session = {
42
- :id => SecureRandom.uuid,
43
- :startedAt => start_time,
44
- :events => {
45
- :handled => 0,
46
- :unhandled => 0
45
+ id: SecureRandom.uuid,
46
+ startedAt: start_time,
47
+ paused?: false,
48
+ events: {
49
+ handled: 0,
50
+ unhandled: 0
47
51
  }
48
52
  }
49
53
  SessionTracker.set_current_session(new_session)
@@ -52,6 +56,47 @@ module Bugsnag
52
56
 
53
57
  alias_method :create_session, :start_session
54
58
 
59
+ ##
60
+ # Stop any events being attributed to the current session until it is
61
+ # resumed or a new session is started
62
+ #
63
+ # @see resume_session
64
+ #
65
+ # @return [void]
66
+ def pause_session
67
+ current_session = SessionTracker.get_current_session
68
+
69
+ return unless current_session
70
+
71
+ current_session[:paused?] = true
72
+ end
73
+
74
+ ##
75
+ # Resume the current session if it was previously paused. If there is no
76
+ # current session, a new session will be started
77
+ #
78
+ # @see pause_session
79
+ #
80
+ # @return [Boolean] true if a paused session was resumed
81
+ def resume_session
82
+ current_session = SessionTracker.get_current_session
83
+
84
+ if current_session
85
+ # if the session is paused then resume it, otherwise we don't need to
86
+ # do anything
87
+ if current_session[:paused?]
88
+ current_session[:paused?] = false
89
+
90
+ return true
91
+ end
92
+ else
93
+ # if there's no current session, start a new one
94
+ start_session
95
+ end
96
+
97
+ false
98
+ end
99
+
55
100
  ##
56
101
  # Delivers the current session_counts lists to the session endpoint.
57
102
  def send_sessions
@@ -83,7 +128,7 @@ module Bugsnag
83
128
  end
84
129
  end
85
130
  end
86
- @delivery_thread = Concurrent::TimerTask.execute(execution_interval: 30) do
131
+ @delivery_thread = Concurrent::TimerTask.execute(execution_interval: 10) do
87
132
  if @session_counts.size > 0
88
133
  send_sessions
89
134
  end
@@ -106,11 +151,6 @@ module Bugsnag
106
151
  return
107
152
  end
108
153
 
109
- if !Bugsnag.configuration.should_notify_release_stage?
110
- Bugsnag.configuration.debug("Not delivering sessions due to notify_release_stages :#{Bugsnag.configuration.notify_release_stages.inspect}")
111
- return
112
- end
113
-
114
154
  body = {
115
155
  :notifier => {
116
156
  :name => Bugsnag::Report::NOTIFIER_NAME,
@@ -43,7 +43,7 @@ module Bugsnag
43
43
  if defined?(configuration.project_root) && configuration.project_root.to_s != ''
44
44
  trace_hash[:inProject] = true if file.start_with?(configuration.project_root.to_s)
45
45
  file.sub!(/#{configuration.project_root}\//, "")
46
- trace_hash.delete(:inProject) if file.match(configuration.vendor_path)
46
+ trace_hash.delete(:inProject) if vendor_path?(configuration, file)
47
47
  end
48
48
 
49
49
  # Strip common gem path prefixes
@@ -67,5 +67,14 @@ module Bugsnag
67
67
 
68
68
  processed_backtrace
69
69
  end
70
+
71
+ # @api private
72
+ def self.vendor_path?(configuration, file_path)
73
+ return true if configuration.vendor_path && file_path.match(configuration.vendor_path)
74
+
75
+ configuration.vendor_paths.any? do |vendor_path|
76
+ file_path.start_with?("#{vendor_path.sub(/\/$/, '')}/")
77
+ end
78
+ end
70
79
  end
71
80
  end
@@ -7,7 +7,7 @@ namespace :bugsnag do
7
7
  raise RuntimeError.new("Bugsnag test exception")
8
8
  rescue => e
9
9
  Bugsnag.notify(e) do |report|
10
- report.context = "rake#test_exception"
10
+ report.automatic_context = "rake#test_exception"
11
11
  end
12
12
  end
13
13
  end
@@ -0,0 +1,124 @@
1
+ module Bugsnag::Utility
2
+ # @api private
3
+ class Duplicator
4
+ class << self
5
+ ##
6
+ # Duplicate (deep clone) the given object
7
+ #
8
+ # @param object [Object]
9
+ # @param seen_objects [Hash<String, Object>]
10
+ # @return [Object]
11
+ def duplicate(object, seen_objects = {})
12
+ case object
13
+ # return immutable & non-duplicatable objects as-is
14
+ when Symbol, Numeric, Method, TrueClass, FalseClass, NilClass
15
+ object
16
+ when Array
17
+ duplicate_array(object, seen_objects)
18
+ when Hash
19
+ duplicate_hash(object, seen_objects)
20
+ when Range
21
+ duplicate_range(object, seen_objects)
22
+ when Struct
23
+ duplicate_struct(object, seen_objects)
24
+ else
25
+ duplicate_generic_object(object, seen_objects)
26
+ end
27
+ rescue StandardError
28
+ object
29
+ end
30
+
31
+ private
32
+
33
+ def duplicate_array(array, seen_objects)
34
+ id = array.object_id
35
+
36
+ return seen_objects[id] if seen_objects.key?(id)
37
+
38
+ copy = array.dup
39
+ seen_objects[id] = copy
40
+
41
+ copy.map! do |value|
42
+ duplicate(value, seen_objects)
43
+ end
44
+
45
+ copy
46
+ end
47
+
48
+ def duplicate_hash(hash, seen_objects)
49
+ id = hash.object_id
50
+
51
+ return seen_objects[id] if seen_objects.key?(id)
52
+
53
+ copy = {}
54
+ seen_objects[id] = copy
55
+
56
+ hash.each do |key, value|
57
+ copy[duplicate(key, seen_objects)] = duplicate(value, seen_objects)
58
+ end
59
+
60
+ copy
61
+ end
62
+
63
+ ##
64
+ # Ranges are immutable but the values they contain may not be
65
+ #
66
+ # For example, a range of "a".."z" can be mutated: range.first.upcase!
67
+ def duplicate_range(range, seen_objects)
68
+ id = range.object_id
69
+
70
+ return seen_objects[id] if seen_objects.key?(id)
71
+
72
+ begin
73
+ copy = range.class.new(
74
+ duplicate(range.first, seen_objects),
75
+ duplicate(range.last, seen_objects),
76
+ range.exclude_end?
77
+ )
78
+ rescue StandardError
79
+ copy = range.dup
80
+ end
81
+
82
+ seen_objects[id] = copy
83
+ end
84
+
85
+ def duplicate_struct(struct, seen_objects)
86
+ id = struct.object_id
87
+
88
+ return seen_objects[id] if seen_objects.key?(id)
89
+
90
+ copy = struct.dup
91
+ seen_objects[id] = copy
92
+
93
+ struct.each_pair do |attribute, value|
94
+ begin
95
+ copy.send("#{attribute}=", duplicate(value, seen_objects))
96
+ rescue StandardError # rubocop:todo Lint/SuppressedException
97
+ end
98
+ end
99
+
100
+ copy
101
+ end
102
+
103
+ def duplicate_generic_object(object, seen_objects)
104
+ id = object.object_id
105
+
106
+ return seen_objects[id] if seen_objects.key?(id)
107
+
108
+ copy = object.dup
109
+ seen_objects[id] = copy
110
+
111
+ begin
112
+ copy.instance_variables.each do |variable|
113
+ value = copy.instance_variable_get(variable)
114
+
115
+ copy.instance_variable_set(variable, duplicate(value, seen_objects))
116
+ end
117
+ rescue StandardError # rubocop:todo Lint/SuppressedException
118
+ end
119
+
120
+ copy
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,102 @@
1
+ module Bugsnag::Utility
2
+ # @api private
3
+ class MetadataDelegate
4
+ # nil is a valid metadata value, so we need a sentinel object so we can tell
5
+ # if the value parameter has been provided
6
+ NOT_PROVIDED = Object.new
7
+
8
+ ##
9
+ # Add values to metadata
10
+ #
11
+ # @overload add_metadata(metadata, section, data)
12
+ # Merges data into the given section of metadata
13
+ # @param metadata [Hash] The metadata hash to operate on
14
+ # @param section [String, Symbol]
15
+ # @param data [Hash]
16
+ #
17
+ # @overload add_metadata(metadata, section, key, value)
18
+ # Sets key to value in the given section of metadata. If the value is nil
19
+ # the key will be deleted
20
+ # @param metadata [Hash] The metadata hash to operate on
21
+ # @param section [String, Symbol]
22
+ # @param key [String, Symbol]
23
+ # @param value
24
+ #
25
+ # @return [void]
26
+ def add_metadata(metadata, section, key_or_data, value = NOT_PROVIDED)
27
+ case value
28
+ when NOT_PROVIDED
29
+ merge_metadata(metadata, section, key_or_data)
30
+ when nil
31
+ clear_metadata(metadata, section, key_or_data)
32
+ else
33
+ overwrite_metadata(metadata, section, key_or_data, value)
34
+ end
35
+ end
36
+
37
+ ##
38
+ # Clear values from metadata
39
+ #
40
+ # @overload clear_metadata(metadata, section)
41
+ # Clears the given section of metadata
42
+ # @param metadata [Hash] The metadata hash to operate on
43
+ # @param section [String, Symbol]
44
+ #
45
+ # @overload clear_metadata(metadata, section, key)
46
+ # Clears the key in the given section of metadata
47
+ # @param metadata [Hash] The metadata hash to operate on
48
+ # @param section [String, Symbol]
49
+ # @param key [String, Symbol]
50
+ #
51
+ # @return [void]
52
+ def clear_metadata(metadata, section, key = nil)
53
+ if key.nil?
54
+ metadata.delete(section)
55
+ elsif metadata[section]
56
+ metadata[section].delete(key)
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ ##
63
+ # Merge new metadata into the existing metadata
64
+ #
65
+ # Any keys with a 'nil' value in the new metadata will be deleted from the
66
+ # existing metadata
67
+ #
68
+ # @param existing_metadata [Hash]
69
+ # @param section [String, Symbol]
70
+ # @param new_metadata [Hash]
71
+ # @return [void]
72
+ def merge_metadata(existing_metadata, section, new_metadata)
73
+ return unless new_metadata.is_a?(Hash)
74
+
75
+ existing_metadata[section] ||= {}
76
+ data = existing_metadata[section]
77
+
78
+ new_metadata.each do |key, value|
79
+ if value.nil?
80
+ data.delete(key)
81
+ else
82
+ data[key] = value
83
+ end
84
+ end
85
+ end
86
+
87
+ ##
88
+ # Overwrite the value in metadata's section & key
89
+ #
90
+ # @param metadata [Hash]
91
+ # @param section [String, Symbol]
92
+ # @param key [String, Symbol]
93
+ # @param value
94
+ # @return [void]
95
+ def overwrite_metadata(metadata, section, key, value)
96
+ return unless key.is_a?(String) || key.is_a?(Symbol)
97
+
98
+ metadata[section] ||= {}
99
+ metadata[section][key] = value
100
+ end
101
+ end
102
+ end
data/lib/bugsnag.rb CHANGED
@@ -5,6 +5,7 @@ require "bugsnag/version"
5
5
  require "bugsnag/configuration"
6
6
  require "bugsnag/meta_data"
7
7
  require "bugsnag/report"
8
+ require "bugsnag/event"
8
9
  require "bugsnag/cleaner"
9
10
  require "bugsnag/helpers"
10
11
  require "bugsnag/session_tracker"
@@ -28,10 +29,14 @@ require "bugsnag/middleware/rake"
28
29
  require "bugsnag/middleware/classify_error"
29
30
  require "bugsnag/middleware/delayed_job"
30
31
 
32
+ require "bugsnag/breadcrumb_type"
31
33
  require "bugsnag/breadcrumbs/validator"
32
34
  require "bugsnag/breadcrumbs/breadcrumb"
33
35
  require "bugsnag/breadcrumbs/breadcrumbs"
34
36
 
37
+ require "bugsnag/utility/duplicator"
38
+ require "bugsnag/utility/metadata_delegate"
39
+
35
40
  # rubocop:todo Metrics/ModuleLength
36
41
  module Bugsnag
37
42
  LOCK = Mutex.new
@@ -79,7 +84,12 @@ module Bugsnag
79
84
  report = Report.new(exception, configuration, auto_notify)
80
85
 
81
86
  # If this is an auto_notify we yield the block before the any middleware is run
82
- yield(report) if block_given? && auto_notify
87
+ begin
88
+ yield(report) if block_given? && auto_notify
89
+ rescue StandardError => e
90
+ configuration.warn("Error in internal notify block: #{e}")
91
+ configuration.warn("Error in internal notify block stacktrace: #{e.backtrace.inspect}")
92
+ end
83
93
 
84
94
  if report.ignore?
85
95
  configuration.debug("Not notifying #{report.exceptions.last[:errorClass]} due to ignore being signified in auto_notify block")
@@ -106,7 +116,12 @@ module Bugsnag
106
116
 
107
117
  # If this is not an auto_notify then the block was provided by the user. This should be the last
108
118
  # block that is run as it is the users "most specific" block.
109
- yield(report) if block_given? && !auto_notify
119
+ begin
120
+ yield(report) if block_given? && !auto_notify
121
+ rescue StandardError => e
122
+ configuration.warn("Error in notify block: #{e}")
123
+ configuration.warn("Error in notify block stacktrace: #{e.backtrace.inspect}")
124
+ end
110
125
 
111
126
  if report.ignore?
112
127
  configuration.debug("Not notifying #{report.exceptions.last[:errorClass]} due to ignore being signified in user provided block")
@@ -122,6 +137,11 @@ module Bugsnag
122
137
  report.severity_reason = initial_reason
123
138
  end
124
139
 
140
+ if report.unhandled_overridden?
141
+ # let the dashboard know that the unhandled flag was overridden
142
+ report.severity_reason[:unhandledOverridden] = true
143
+ end
144
+
125
145
  deliver_notification(report)
126
146
  end
127
147
  end
@@ -177,13 +197,36 @@ module Bugsnag
177
197
  end
178
198
 
179
199
  ##
180
- # Starts a session.
200
+ # Starts a new session, which allows Bugsnag to track error rates across
201
+ # releases
181
202
  #
182
- # Allows Bugsnag to track error rates across releases.
203
+ # @return [void]
183
204
  def start_session
184
205
  session_tracker.start_session
185
206
  end
186
207
 
208
+ ##
209
+ # Stop any events being attributed to the current session until it is
210
+ # resumed or a new session is started
211
+ #
212
+ # @see resume_session
213
+ #
214
+ # @return [void]
215
+ def pause_session
216
+ session_tracker.pause_session
217
+ end
218
+
219
+ ##
220
+ # Resume the current session if it was previously paused. If there is no
221
+ # current session, a new session will be started
222
+ #
223
+ # @see pause_session
224
+ #
225
+ # @return [Boolean] true if a paused session was resumed
226
+ def resume_session
227
+ session_tracker.resume_session
228
+ end
229
+
187
230
  ##
188
231
  # Allow access to "before notify" callbacks as an array.
189
232
  #
@@ -227,7 +270,7 @@ module Bugsnag
227
270
  #
228
271
  # @param name [String] the main breadcrumb name/message
229
272
  # @param meta_data [Hash] String, Numeric, or Boolean meta data to attach
230
- # @param type [String] the breadcrumb type, from Bugsnag::Breadcrumbs::VALID_BREADCRUMB_TYPES
273
+ # @param type [String] the breadcrumb type, see {Bugsnag::BreadcrumbType}
231
274
  # @param auto [Symbol] set to :auto if the breadcrumb is automatically created
232
275
  # @return [void]
233
276
  def leave_breadcrumb(name, meta_data={}, type=Bugsnag::Breadcrumbs::MANUAL_BREADCRUMB_TYPE, auto=:manual)
@@ -240,7 +283,7 @@ module Bugsnag
240
283
  # Skip if it's already invalid
241
284
  return if breadcrumb.ignore?
242
285
 
243
- # Run callbacks
286
+ # Run before_breadcrumb_callbacks
244
287
  configuration.before_breadcrumb_callbacks.each do |c|
245
288
  c.arity > 0 ? c.call(breadcrumb) : c.call
246
289
  break if breadcrumb.ignore?
@@ -249,6 +292,10 @@ module Bugsnag
249
292
  # Return early if ignored
250
293
  return if breadcrumb.ignore?
251
294
 
295
+ # Run on_breadcrumb callbacks
296
+ configuration.on_breadcrumb_callbacks.call(breadcrumb)
297
+ return if breadcrumb.ignore?
298
+
252
299
  # Validate again in case of callback alteration
253
300
  validator.validate(breadcrumb)
254
301
 
@@ -265,7 +312,7 @@ module Bugsnag
265
312
  # Returning false from an on_error callback will cause the error to be ignored
266
313
  # and will prevent any remaining callbacks from being called
267
314
  #
268
- # @param callback [Proc]
315
+ # @param callback [Proc, Method, #call]
269
316
  # @return [void]
270
317
  def add_on_error(callback)
271
318
  configuration.add_on_error(callback)
@@ -283,6 +330,44 @@ module Bugsnag
283
330
  configuration.remove_on_error(callback)
284
331
  end
285
332
 
333
+ ##
334
+ # Add the given callback to the list of on_breadcrumb callbacks
335
+ #
336
+ # The on_breadcrumb callbacks will be called when a breadcrumb is left and
337
+ # are passed the {Breadcrumbs::Breadcrumb Breadcrumb} object
338
+ #
339
+ # Returning false from an on_breadcrumb callback will cause the breadcrumb
340
+ # to be ignored and will prevent any remaining callbacks from being called
341
+ #
342
+ # @param callback [Proc, Method, #call]
343
+ # @return [void]
344
+ def add_on_breadcrumb(callback)
345
+ configuration.add_on_breadcrumb(callback)
346
+ end
347
+
348
+ ##
349
+ # Remove the given callback from the list of on_breadcrumb callbacks
350
+ #
351
+ # Note that this must be the same instance that was passed to
352
+ # {add_on_breadcrumb}, otherwise it will not be removed
353
+ #
354
+ # @param callback [Proc, Method, #call]
355
+ # @return [void]
356
+ def remove_on_breadcrumb(callback)
357
+ configuration.remove_on_breadcrumb(callback)
358
+ end
359
+
360
+ ##
361
+ # Returns the current list of breadcrumbs
362
+ #
363
+ # This is a per-thread circular buffer, containing at most 'max_breadcrumbs'
364
+ # breadcrumbs
365
+ #
366
+ # @return [Bugsnag::Utility::CircularBuffer]
367
+ def breadcrumbs
368
+ configuration.breadcrumbs
369
+ end
370
+
286
371
  ##
287
372
  # Returns the client's Cleaner object, or creates one if not yet created.
288
373
  #
@@ -296,9 +381,56 @@ module Bugsnag
296
381
  end
297
382
  end
298
383
 
384
+ ##
385
+ # Global metadata added to every event
386
+ #
387
+ # @return [Hash]
388
+ def metadata
389
+ configuration.metadata
390
+ end
391
+
392
+ ##
393
+ # Add values to metadata
394
+ #
395
+ # @overload add_metadata(section, data)
396
+ # Merges data into the given section of metadata
397
+ # @param section [String, Symbol]
398
+ # @param data [Hash]
399
+ #
400
+ # @overload add_metadata(section, key, value)
401
+ # Sets key to value in the given section of metadata. If the value is nil
402
+ # the key will be deleted
403
+ # @param section [String, Symbol]
404
+ # @param key [String, Symbol]
405
+ # @param value
406
+ #
407
+ # @return [void]
408
+ def add_metadata(section, key_or_data, *args)
409
+ configuration.add_metadata(section, key_or_data, *args)
410
+ end
411
+
412
+ ##
413
+ # Clear values from metadata
414
+ #
415
+ # @overload clear_metadata(section)
416
+ # Clears the given section of metadata
417
+ # @param section [String, Symbol]
418
+ #
419
+ # @overload clear_metadata(section, key)
420
+ # Clears the key in the given section of metadata
421
+ # @param section [String, Symbol]
422
+ # @param key [String, Symbol]
423
+ #
424
+ # @return [void]
425
+ def clear_metadata(section, *args)
426
+ configuration.clear_metadata(section, *args)
427
+ end
428
+
299
429
  private
300
430
 
301
431
  def should_deliver_notification?(exception, auto_notify)
432
+ return false unless configuration.enable_events
433
+
302
434
  reason = abort_reason(exception, auto_notify)
303
435
  configuration.debug(reason) unless reason.nil?
304
436
  reason.nil?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bugsnag
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.20.0
4
+ version: 6.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-29 00:00:00.000000000 Z
11
+ date: 2021-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -40,8 +40,10 @@ files:
40
40
  - VERSION
41
41
  - bugsnag.gemspec
42
42
  - lib/bugsnag.rb
43
+ - lib/bugsnag/breadcrumb_type.rb
43
44
  - lib/bugsnag/breadcrumbs/breadcrumb.rb
44
45
  - lib/bugsnag/breadcrumbs/breadcrumbs.rb
46
+ - lib/bugsnag/breadcrumbs/on_breadcrumb_callback_list.rb
45
47
  - lib/bugsnag/breadcrumbs/validator.rb
46
48
  - lib/bugsnag/cleaner.rb
47
49
  - lib/bugsnag/code_extractor.rb
@@ -49,12 +51,17 @@ files:
49
51
  - lib/bugsnag/delivery.rb
50
52
  - lib/bugsnag/delivery/synchronous.rb
51
53
  - lib/bugsnag/delivery/thread_queue.rb
54
+ - lib/bugsnag/endpoint_configuration.rb
55
+ - lib/bugsnag/endpoint_validator.rb
56
+ - lib/bugsnag/error.rb
57
+ - lib/bugsnag/event.rb
52
58
  - lib/bugsnag/helpers.rb
53
59
  - lib/bugsnag/integrations/delayed_job.rb
54
60
  - lib/bugsnag/integrations/mailman.rb
55
61
  - lib/bugsnag/integrations/mongo.rb
56
62
  - lib/bugsnag/integrations/que.rb
57
63
  - lib/bugsnag/integrations/rack.rb
64
+ - lib/bugsnag/integrations/rails/active_job.rb
58
65
  - lib/bugsnag/integrations/rails/active_record_rescue.rb
59
66
  - lib/bugsnag/integrations/rails/controller_methods.rb
60
67
  - lib/bugsnag/integrations/rails/rails_breadcrumbs.rb
@@ -64,6 +71,7 @@ files:
64
71
  - lib/bugsnag/integrations/shoryuken.rb
65
72
  - lib/bugsnag/integrations/sidekiq.rb
66
73
  - lib/bugsnag/meta_data.rb
74
+ - lib/bugsnag/middleware/active_job.rb
67
75
  - lib/bugsnag/middleware/breadcrumbs.rb
68
76
  - lib/bugsnag/middleware/callbacks.rb
69
77
  - lib/bugsnag/middleware/classify_error.rb
@@ -88,6 +96,8 @@ files:
88
96
  - lib/bugsnag/tasks.rb
89
97
  - lib/bugsnag/tasks/bugsnag.rake
90
98
  - lib/bugsnag/utility/circular_buffer.rb
99
+ - lib/bugsnag/utility/duplicator.rb
100
+ - lib/bugsnag/utility/metadata_delegate.rb
91
101
  - lib/bugsnag/version.rb
92
102
  - lib/generators/bugsnag/bugsnag_generator.rb
93
103
  homepage: https://github.com/bugsnag/bugsnag-ruby