bugsnag 6.20.0 → 6.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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