rollbar 2.22.1 → 2.23.0

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: c56a90107593b66c2be899fd4f36abe3ad657abcd0e2d822964efbc8e47efdbb
4
- data.tar.gz: cd95d87f45d3e65f3dc499c9be88c3c18b84ccd359eda34ed2ab88e941909754
3
+ metadata.gz: a50cc143ea1aa3a6add2c00d309896a3710a46badb9766bbe483493573ed3529
4
+ data.tar.gz: 0b0adcbf6fe2c7f34d45a637b1094635d02549a1b482f20ca6d2fcc8f61c794b
5
5
  SHA512:
6
- metadata.gz: c6fe31a226014d67e1225234e408030b1e9bab112973e3a312607e26c71c98e6c64d56d7ea2163e0d1cfdd5af3755c384e15c6e11c3166f9478b384f4c0a512f
7
- data.tar.gz: 12c63a9346dc60827b7b5765b6e63ce9d5c814fdb90c0e685952e4751669bb0f0770344830d625070cac6d656958f6bbd2862522cd7d51d1e0cae039bfd0efb5
6
+ metadata.gz: bfa2037aa71e31c48c8bbe1ee8b4fec69225ee705500bdf04c9f872188d721571d58e60c7ddcc1783b778a2182c0dfd8a27be22e3cd76143a9964a2ad873dcef
7
+ data.tar.gz: 0f1dd72f99f40672c779bcaf2750c1e0aa7a094fb205bc750fa32ea3d6d2121ac9852f43d0b69ce5543d851ac3c72723e0e5579330e1de7de00058605c58ee60
@@ -1,3 +1,5 @@
1
+ require: rubocop-performance
2
+
1
3
  AllCops:
2
4
  Exclude:
3
5
  - 'vendor/**/*'
@@ -66,3 +68,133 @@ Style/FrozenStringLiteralComment:
66
68
  # If we do this, it will be in its own PR. It requires adding these magic comments
67
69
  # throughout the project, in order to prepare for a future Ruby 3.x.
68
70
  Enabled: false
71
+
72
+ #
73
+ # Performance cops are opt in, and `Enabled: true` is always required.
74
+ # Full list is here: https://github.com/rubocop-hq/rubocop-performance/tree/master/lib/rubocop/cop/performance
75
+ # For travis builds, Codacy will see and use these directives.
76
+ #
77
+ Performance/Caller:
78
+ Enabled: true
79
+ Exclude:
80
+ - spec/**/*
81
+
82
+ Performance/CaseWhenSplat:
83
+ Enabled: true
84
+ Exclude:
85
+ - spec/**/*
86
+
87
+ Performance/Casecmp:
88
+ Enabled: true
89
+ Exclude:
90
+ - spec/**/*
91
+
92
+ Performance/ChainArrayAllocation:
93
+ Enabled: true
94
+ Exclude:
95
+ - spec/**/*
96
+
97
+ Performance/CompareWithBlock:
98
+ Enabled: true
99
+ Exclude:
100
+ - spec/**/*
101
+
102
+ Performance/Count:
103
+ Enabled: true
104
+ Exclude:
105
+ - spec/**/*
106
+
107
+ Performance/Detect:
108
+ Enabled: true
109
+ Exclude:
110
+ - spec/**/*
111
+
112
+ Performance/DoubleStartEndWith:
113
+ Enabled: true
114
+ Exclude:
115
+ - spec/**/*
116
+
117
+ Performance/EndWith:
118
+ Enabled: true
119
+ Exclude:
120
+ - spec/**/*
121
+
122
+ Performance/FixedSize:
123
+ Enabled: true
124
+ Exclude:
125
+ - spec/**/*
126
+
127
+ Performance/FlatMap:
128
+ Enabled: true
129
+ Exclude:
130
+ - spec/**/*
131
+
132
+ Performance/InefficientHashSearch:
133
+ Enabled: true
134
+ Exclude:
135
+ - spec/**/*
136
+
137
+ Performance/OpenStruct:
138
+ Enabled: true
139
+ Exclude:
140
+ - spec/**/*
141
+
142
+ Performance/RangeInclude:
143
+ Enabled: true
144
+ Exclude:
145
+ - spec/**/*
146
+
147
+ Performance/RedundantBlockCall:
148
+ Enabled: true
149
+ Exclude:
150
+ - spec/**/*
151
+
152
+ Performance/RedundantMatch:
153
+ Enabled: true
154
+ Exclude:
155
+ - spec/**/*
156
+
157
+ Performance/RedundantMerge:
158
+ Enabled: true
159
+ Exclude:
160
+ - spec/**/*
161
+
162
+ Performance/RegexpMatch:
163
+ Enabled: true
164
+ Exclude:
165
+ - spec/**/*
166
+
167
+ Performance/ReverseEach:
168
+ Enabled: true
169
+ Exclude:
170
+ - spec/**/*
171
+
172
+ Performance/Size:
173
+ Enabled: true
174
+ Exclude:
175
+ - spec/**/*
176
+
177
+ Performance/StartWith:
178
+ Enabled: true
179
+ Exclude:
180
+ - spec/**/*
181
+
182
+ Performance/StringReplacement:
183
+ Enabled: true
184
+ Exclude:
185
+ - spec/**/*
186
+
187
+ Performance/TimesMap:
188
+ Enabled: true
189
+ Exclude:
190
+ - spec/**/*
191
+
192
+ Performance/UnfreezeString:
193
+ Enabled: true
194
+ Exclude:
195
+ - spec/**/*
196
+
197
+ Performance/UriDefaultParser:
198
+ Enabled: true
199
+ Exclude:
200
+ - spec/**/*
@@ -184,11 +184,14 @@ matrix:
184
184
  gemfile: gemfiles/rails52.gemfile
185
185
  - rvm: 2.1.0
186
186
  gemfile: gemfiles/rails60.gemfile
187
- # MRI 2.2.2 supports Rails 3.2.x and higher
187
+ # MRI 2.2.2 supports Rails 3.2.x and higher, except Rails 5.2.4 and higher*
188
+ # * ActionDispatch 5.2.4 uses Ruby 3.x safe navigation operator.
188
189
  - rvm: 2.2.2
189
190
  gemfile: gemfiles/rails30.gemfile
190
191
  - rvm: 2.2.2
191
192
  gemfile: gemfiles/rails31.gemfile
193
+ - rvm: 2.2.2
194
+ gemfile: gemfiles/rails52.gemfile
192
195
  # MRI 2.3.x supports Rails 4.0.x and higher
193
196
  - rvm: 2.3.8
194
197
  gemfile: gemfiles/rails30.gemfile
data/Gemfile CHANGED
@@ -46,6 +46,7 @@ end
46
46
 
47
47
  if RUBY_VERSION.start_with?('1.9')
48
48
  gem 'capistrano', '<= 3.4.1', :require => false
49
+ gem 'json', '1.8.6'
49
50
  gem 'shoryuken', '>= 4.0.0', '<= 4.0.2'
50
51
  gem 'sucker_punch', '~> 1.0'
51
52
  elsif RUBY_VERSION.start_with?('2')
@@ -73,6 +74,7 @@ gem 'girl_friday', '>= 0.11.1'
73
74
  gem 'redis'
74
75
  gem 'resque', '< 2.0.0'
75
76
  gem 'rubocop', :require => false
77
+ gem 'rubocop-performance', :require => false
76
78
  gem 'sinatra'
77
79
  gem 'webmock', :require => false
78
80
  gemspec
@@ -27,6 +27,10 @@ platforms :rbx do
27
27
  gem 'rubysl', '~> 2.0' unless RUBY_VERSION.start_with?('1')
28
28
  end
29
29
 
30
+ if RUBY_VERSION < '2.0.0'
31
+ gem 'json', '1.8.6'
32
+ end
33
+
30
34
  if RUBY_VERSION < '2.2.2'
31
35
  gem 'sidekiq', '~> 2.13.0'
32
36
  else
@@ -17,6 +17,7 @@ module Rollbar
17
17
  attr_accessor :disable_monkey_patch
18
18
  attr_accessor :disable_rack_monkey_patch
19
19
  attr_accessor :disable_core_monkey_patch
20
+ attr_accessor :enable_error_context
20
21
  attr_accessor :dj_threshold
21
22
  attr_accessor :enabled
22
23
  attr_accessor :endpoint
@@ -57,6 +58,7 @@ module Rollbar
57
58
  attr_reader :transform
58
59
  attr_accessor :verify_ssl_peer
59
60
  attr_accessor :use_async
61
+ attr_accessor :async_json_payload
60
62
  attr_reader :use_eventmachine
61
63
  attr_accessor :web_base
62
64
  attr_accessor :write_to_file
@@ -66,6 +68,7 @@ module Rollbar
66
68
  attr_accessor :raise_on_error
67
69
  attr_accessor :transmit
68
70
  attr_accessor :log_payload
71
+ attr_accessor :backtrace_cleaner
69
72
 
70
73
  attr_reader :project_gem_paths
71
74
  attr_accessor :configured_options
@@ -87,6 +90,7 @@ module Rollbar
87
90
  @disable_monkey_patch = false
88
91
  @disable_core_monkey_patch = false
89
92
  @disable_rack_monkey_patch = false
93
+ @enable_error_context = true
90
94
  @dj_threshold = 0
91
95
  @enabled = nil # set to true when configure is called
92
96
  @endpoint = DEFAULT_ENDPOINT
@@ -118,7 +122,7 @@ module Rollbar
118
122
  :api_key, :access_token, :accessToken, :session_id]
119
123
  @scrub_user = true
120
124
  @scrub_password = true
121
- @randomize_scrub_length = true
125
+ @randomize_scrub_length = false
122
126
  @scrub_whitelist = []
123
127
  @uncaught_exception_level = 'error'
124
128
  @scrub_headers = ['Authorization']
@@ -126,6 +130,7 @@ module Rollbar
126
130
  @safely = false
127
131
  @transform = []
128
132
  @use_async = false
133
+ @async_json_payload = false
129
134
  @use_eventmachine = false
130
135
  @verify_ssl_peer = true
131
136
  @web_base = DEFAULT_WEB_BASE
@@ -139,6 +144,7 @@ module Rollbar
139
144
  @log_payload = false
140
145
  @collect_user_ip = true
141
146
  @anonymize_user_ip = false
147
+ @backtrace_cleaner = nil
142
148
  @hooks = {
143
149
  :on_error_response => nil, # params: response
144
150
  :on_report_internal_error => nil # params: exception
@@ -232,9 +238,10 @@ module Rollbar
232
238
  value.is_a?(Hash) ? use_sidekiq(value) : use_sidekiq
233
239
  end
234
240
 
235
- def use_thread
241
+ def use_thread(options = {})
236
242
  require 'rollbar/delay/thread'
237
243
  @use_async = true
244
+ Rollbar::Delay::Thread.options = options
238
245
  @async_handler = Rollbar::Delay::Thread
239
246
  end
240
247
 
@@ -261,7 +268,10 @@ module Rollbar
261
268
  found = Gem::Specification.each.select { |spec| name === spec.name }
262
269
  puts "[Rollbar] No gems found matching #{name.inspect}" if found.empty?
263
270
  found
264
- end.flatten.uniq.map(&:gem_dir)
271
+ end
272
+ @project_gem_paths.flatten!
273
+ @project_gem_paths.uniq!
274
+ @project_gem_paths.map!(&:gem_dir)
265
275
  end
266
276
 
267
277
  def before_process=(*handler)
@@ -12,13 +12,9 @@ module Rollbar
12
12
 
13
13
  def queue
14
14
  @queue ||= queue_class.new(nil, :size => 5) do |payload|
15
- begin
16
- Rollbar.process_from_async_handler(payload)
17
- rescue StandardError
18
- # According to https://github.com/mperham/girl_friday/wiki#error-handling
19
- # we reraise the exception so it can be handled some way
20
- raise
21
- end
15
+ Rollbar.process_from_async_handler(payload)
16
+
17
+ # Do not rescue. GirlFriday will call the error handler.
22
18
  end
23
19
  end
24
20
  end
@@ -24,9 +24,8 @@ module Rollbar
24
24
 
25
25
  def perform(payload)
26
26
  Rollbar.process_from_async_handler(payload)
27
- rescue StandardError
28
- # Raise the exception so Resque can track the errored job
29
- raise
27
+
28
+ # Do not rescue. Resque will call the error handler.
30
29
  end
31
30
  end
32
31
  end
@@ -17,10 +17,8 @@ module Rollbar
17
17
 
18
18
  def perform(*args)
19
19
  Rollbar.process_from_async_handler(*args)
20
- rescue StandardError
21
- # Raise the exception so Sidekiq can track the errored job
22
- # and retry it
23
- raise
20
+
21
+ # Do not rescue. Sidekiq will call the error handler.
24
22
  end
25
23
  end
26
24
  end
@@ -33,7 +33,7 @@ module Rollbar
33
33
 
34
34
  def perform(*args)
35
35
  Rollbar.process_from_async_handler(*args)
36
- rescue StandardError
36
+
37
37
  # SuckerPunch can configure an exception handler with:
38
38
  #
39
39
  # SuckerPunch.exception_handler { # do something here }
@@ -41,9 +41,8 @@ module Rollbar
41
41
  # This is just passed to Celluloid.exception_handler which will
42
42
  # push the reiceved block to an array of handlers, by default empty, [].
43
43
  #
44
- # We reraise the exception here casue it's safe and users could have defined
45
- # their own exception handler for SuckerPunch
46
- raise
44
+
45
+ # Do not rescue. SuckerPunch will call the error handler.
47
46
  end
48
47
  end
49
48
  end
@@ -9,7 +9,10 @@ module Rollbar
9
9
  Error = Class.new(StandardError)
10
10
  TimeoutError = Class.new(Error)
11
11
 
12
+ DEFAULT_PRIORITY = 1
13
+
12
14
  class << self
15
+ attr_writer :options
13
16
  attr_reader :reaper
14
17
 
15
18
  def call(payload)
@@ -20,6 +23,10 @@ module Rollbar
20
23
  thread
21
24
  end
22
25
 
26
+ def options
27
+ @options || {}
28
+ end
29
+
23
30
  private
24
31
 
25
32
  def threads
@@ -61,9 +68,16 @@ module Rollbar
61
68
  end
62
69
  end # class << self
63
70
 
71
+ def priority
72
+ self.class.options[:priority] || DEFAULT_PRIORITY
73
+ end
74
+
64
75
  def call(payload)
76
+ priority = self.priority
77
+
65
78
  ::Thread.new do
66
79
  begin
80
+ ::Thread.current.priority = priority
67
81
  Rollbar.process_from_async_handler(payload)
68
82
  rescue StandardError
69
83
  # Here we swallow the exception:
@@ -109,15 +109,11 @@ module Rollbar
109
109
  # the risk just to send this diagnostic object. In versions < 4.1, ActiveSupport hooks
110
110
  # Ruby's JSON.generate so deeply there's no workaround.
111
111
  'not serialized in ActiveSupport < 4.1'
112
- elsif configuration.use_async
113
- # Currently serialization is performed by each handler, and this invariably
114
- # means it is actually performed by ActiveSupport.
115
- #
116
- # TODO: Since serialization must be done prior to scheduling the job,
117
- # it should at least be done by rollbar-gem itself. Much work has been done
118
- # to avoid the bugs in ActiveSupport JSON. The async handlers are currently
119
- # still subject to all those knnown issues.
120
- 'not serialized for async/delayed handlers'
112
+ elsif configuration.use_async && !configuration.async_json_payload
113
+ # The setting allows serialization to be performed by each handler,
114
+ # and this usually means it is actually performed by ActiveSupport,
115
+ # which cannot safely serialize this key.
116
+ 'not serialized when async_json_payload is not set'
121
117
  else
122
118
  scrub(configuration.configured_options.configured)
123
119
  end
@@ -187,13 +183,19 @@ module Rollbar
187
183
  end
188
184
 
189
185
  def build_extra
186
+ merged_extra = Util.deep_merge(scrub(extra), scrub(error_context))
187
+
190
188
  if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
191
- Util.deep_merge(scrub(custom_data), scrub(extra) || {})
189
+ Util.deep_merge(scrub(custom_data), merged_extra)
192
190
  else
193
- scrub(extra)
191
+ merged_extra.empty? ? nil : merged_extra # avoid putting an empty {} in the payload.
194
192
  end
195
193
  end
196
194
 
195
+ def error_context
196
+ exception.respond_to?(:rollbar_context) && exception.rollbar_context
197
+ end
198
+
197
199
  def scrub(data)
198
200
  return data unless data.is_a? Hash
199
201
 
@@ -55,7 +55,7 @@ module Rollbar
55
55
  current_exception = exception
56
56
 
57
57
  while current_exception.respond_to?(:cause) && (cause = current_exception.cause) && cause.is_a?(Exception) && !visited.include?(cause)
58
- traces << trace_data(cause)
58
+ traces.unshift(trace_data(cause))
59
59
  visited << cause
60
60
  current_exception = cause
61
61
  end
@@ -74,10 +74,20 @@ module Rollbar
74
74
  end
75
75
 
76
76
  def map_frames(current_exception)
77
- exception_backtrace(current_exception).map do |frame|
77
+ frames = cleaned_backtrace(current_exception).map do |frame|
78
78
  Rollbar::Item::Frame.new(self, frame,
79
79
  :configuration => configuration).to_h
80
- end.reverse
80
+ end
81
+ frames.reverse!
82
+ end
83
+
84
+ def cleaned_backtrace(current_exception)
85
+ normalized_backtrace = exception_backtrace(current_exception)
86
+ if configuration.backtrace_cleaner
87
+ configuration.backtrace_cleaner.clean(normalized_backtrace)
88
+ else
89
+ normalized_backtrace
90
+ end
81
91
  end
82
92
 
83
93
  # Returns the backtrace to be sent to our API. There are 3 options:
@@ -97,6 +97,8 @@ module Rollbar
97
97
  end
98
98
 
99
99
  def locals_data(filename, lineno)
100
+ return unless configuration.locals[:enabled]
101
+
100
102
  ::Rollbar::Item::Locals.locals_for_location(filename, lineno)
101
103
  end
102
104
 
@@ -1,5 +1,6 @@
1
1
  require 'rollbar/notifier'
2
2
  require 'rollbar/scrubbers/params'
3
+ require 'rollbar/util'
3
4
 
4
5
  module Rollbar
5
6
  class Item
@@ -39,8 +40,51 @@ module Rollbar
39
40
  end
40
41
  end
41
42
 
43
+ # Prepare objects to be handled by the payload serializer.
44
+ #
45
+ # Hashes and Arrays are traversed. Then all types execpt strings and
46
+ # immediates are exported using #inspect. Sending the object itself to the
47
+ # serializer can result in large recursive expansions, especially in Rails
48
+ # environments with ActiveRecord, ActiveSupport, etc. on the stack.
49
+ # Other export options could be #to_s, #to_h, and #as_json. Several of these
50
+ # will omit the class name, or are not implemented for many types.
51
+ #
52
+ # #inspect has the advantage that it is specifically intended for debugging
53
+ # output. If the user wants more or different information in the payload
54
+ # about a specific type, #inspect is the correct place to implement it.
55
+ # Likewise the default implementation should be oriented toward usefulness
56
+ # in debugging.
57
+ #
58
+ # Because #inspect outputs a string, it can be handled well by the string
59
+ # truncation strategy for large payloads.
60
+ #
42
61
  def prepare_value(value)
43
- value.to_s
62
+ return simple_value?(value) ? value : value.inspect unless value.is_a?(Hash) || value.is_a?(Array)
63
+
64
+ cloned_value = ::Rollbar::Util.deep_copy(value)
65
+ ::Rollbar::Util.iterate_and_update_with_block(cloned_value) do |v|
66
+ simple_value?(v) ? v : v.inspect
67
+ end
68
+
69
+ cloned_value
70
+ end
71
+
72
+ def simple_classes
73
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
74
+ [String, Symbol, Integer, Float, TrueClass, FalseClass, NilClass]
75
+ else
76
+ [String, Symbol, Fixnum, Bignum, Float, TrueClass, FalseClass, NilClass] # rubocop:disable Lint/UnifiedInteger
77
+ end
78
+ end
79
+
80
+ def simple_value?(value)
81
+ simple_classes.each do |klass|
82
+ # Use instance_of? so that subclasses and module containers will
83
+ # be treated like complex object types, not simple values.
84
+ return true if value.instance_of?(klass)
85
+ end
86
+
87
+ false
44
88
  end
45
89
 
46
90
  def scrub(hash)
@@ -211,7 +211,9 @@ module Rollbar
211
211
  end
212
212
  rescue StandardError => e
213
213
  log_error("[Rollbar] Error processing the item: #{e.class}, #{e.message}. Item: #{item.payload.inspect}")
214
- raise e
214
+ raise e unless via_failsafe?(item)
215
+
216
+ log_error('[Rollbar] Item has already failed. Not re-raising')
215
217
  end
216
218
 
217
219
  # We will reraise exceptions in this method so async queues
@@ -238,16 +240,19 @@ module Rollbar
238
240
  # Using Rollbar.silenced we avoid the above behavior but Sidekiq
239
241
  # will have a chance to retry the original job.
240
242
  def process_from_async_handler(payload)
241
- payload = Rollbar::JSON.load(payload) if payload.is_a?(String)
242
-
243
- item = Item.build_with(payload,
244
- :notifier => self,
245
- :configuration => configuration,
246
- :logger => logger)
247
-
248
243
  Rollbar.silenced do
249
244
  begin
250
- process_item(item)
245
+ if payload.is_a?(String)
246
+ # The final payload has already been built.
247
+ send_body(payload)
248
+ else
249
+ item = Item.build_with(payload,
250
+ :notifier => self,
251
+ :configuration => configuration,
252
+ :logger => logger)
253
+
254
+ process_item(item)
255
+ end
251
256
  rescue StandardError => e
252
257
  report_internal_error(e)
253
258
 
@@ -509,14 +514,18 @@ module Rollbar
509
514
 
510
515
  ## Delivery functions
511
516
 
512
- def send_item_using_eventmachine(item, uri)
513
- body = item.dump
514
- return unless body
517
+ def send_using_eventmachine(body)
518
+ uri = URI.parse(configuration.endpoint)
515
519
 
516
- headers = { 'X-Rollbar-Access-Token' => item['access_token'] }
520
+ headers = { 'X-Rollbar-Access-Token' => configuration.access_token }
517
521
  options = http_proxy_for_em(uri)
518
522
  req = EventMachine::HttpRequest.new(uri.to_s, options).post(:body => body, :head => headers)
519
523
 
524
+ eventmachine_callback(req)
525
+ eventmachine_errback(req)
526
+ end
527
+
528
+ def eventmachine_callback(req)
520
529
  req.callback do
521
530
  if req.response_header.status == 200
522
531
  log_info '[Rollbar] Success'
@@ -525,7 +534,9 @@ module Rollbar
525
534
  log_info "[Rollbar] Response: #{req.response}"
526
535
  end
527
536
  end
537
+ end
528
538
 
539
+ def eventmachine_errback(req)
529
540
  req.errback do
530
541
  log_warning "[Rollbar] Call to API failed, status code: #{req.response_header.status}"
531
542
  log_info "[Rollbar] Error's response: #{req.response}"
@@ -538,14 +549,20 @@ module Rollbar
538
549
  body = item.dump
539
550
  return unless body
540
551
 
541
- uri = URI.parse(configuration.endpoint)
542
-
543
552
  if configuration.use_eventmachine
544
- send_item_using_eventmachine(item, uri)
553
+ send_using_eventmachine(body)
545
554
  return
546
555
  end
547
556
 
548
- handle_response(do_post(uri, body, item['access_token']))
557
+ send_body(body)
558
+ end
559
+
560
+ def send_body(body)
561
+ log_info '[Rollbar] Sending json'
562
+
563
+ uri = URI.parse(configuration.endpoint)
564
+
565
+ handle_response(do_post(uri, body, configuration.access_token))
549
566
  end
550
567
 
551
568
  def do_post(uri, body, access_token)
@@ -737,8 +754,11 @@ module Rollbar
737
754
  end
738
755
 
739
756
  def process_async_item(item)
757
+ # Send async payloads as JSON string when async_json_payload is set.
758
+ payload = configuration.async_json_payload ? item.dump : item.payload
759
+
740
760
  configuration.async_handler ||= default_async_handler
741
- configuration.async_handler.call(item.payload)
761
+ configuration.async_handler.call(payload)
742
762
  rescue StandardError
743
763
  if configuration.failover_handlers.empty?
744
764
  log_error '[Rollbar] Async handler failed, and there are no failover handlers configured. See the docs for "failover_handlers"'
@@ -772,5 +792,9 @@ module Rollbar
772
792
  uuid_url = Util.uuid_rollbar_url(data, configuration)
773
793
  log_info "[Rollbar] Details: #{uuid_url} (only available if report was successful)"
774
794
  end
795
+
796
+ def via_failsafe?(item)
797
+ item.payload.fetch('data', {}).fetch(:failsafe, false)
798
+ end
775
799
  end
776
800
  end
@@ -14,5 +14,7 @@ module Rollbar
14
14
  end
15
15
  end
16
16
 
17
- # Automatically add to ActionMailer::DeliveryJob
18
- ActionMailer::DeliveryJob.send(:include, Rollbar::ActiveJob) if defined?(ActionMailer::DeliveryJob)
17
+ ActiveSupport.on_load(:action_mailer) do
18
+ # Automatically add to ActionMailer::DeliveryJob
19
+ ActionMailer::DeliveryJob.send(:include, Rollbar::ActiveJob) if defined?(ActionMailer::DeliveryJob)
20
+ end
@@ -0,0 +1,11 @@
1
+ module RollbarErrorContext
2
+ attr_accessor :rollbar_context
3
+ end
4
+
5
+ Rollbar.plugins.define('error_context') do
6
+ dependency { configuration.enable_error_context }
7
+
8
+ execute! do
9
+ StandardError.send(:include, RollbarErrorContext)
10
+ end
11
+ end
@@ -6,11 +6,7 @@ module Rollbar
6
6
  if Rollbar.configuration.randomize_scrub_length
7
7
  random_filtered_value
8
8
  else
9
- '*' * (begin
10
- value.length
11
- rescue StandardError
12
- 8
13
- end)
9
+ '*' * 6
14
10
  end
15
11
  end
16
12
 
@@ -11,7 +11,7 @@ module Rollbar
11
11
  end
12
12
 
13
13
  def call(payload)
14
- new_payload = Rollbar::Util.deep_copy(payload)
14
+ new_payload = payload
15
15
  body = new_payload['data']['body']
16
16
 
17
17
  if body['trace_chain']
@@ -9,7 +9,7 @@ module Rollbar
9
9
  result.bytesize > MAX_PAYLOAD_SIZE
10
10
  end
11
11
 
12
- def select_frames(frames, range = 150)
12
+ def select_frames(frames, range = 50)
13
13
  return frames unless frames.count > range * 2
14
14
 
15
15
  frames[0, range] + frames[-range, range]
@@ -6,7 +6,7 @@ module Rollbar
6
6
  class StringsStrategy
7
7
  include ::Rollbar::Truncation::Mixin
8
8
 
9
- STRING_THRESHOLDS = [1024, 512, 256].freeze
9
+ STRING_THRESHOLDS = [1024, 512, 256, 128].freeze
10
10
 
11
11
  def self.call(payload)
12
12
  new.call(payload)
@@ -29,7 +29,9 @@ module Rollbar
29
29
 
30
30
  def truncate_strings_proc(threshold)
31
31
  proc do |value|
32
- if value.is_a?(String) && value.bytesize > threshold
32
+ # Rollbar::Util.truncate will operate on characters, not bytes,
33
+ # so use value.length, not bytesize.
34
+ if value.is_a?(String) && value.length > threshold
33
35
  Rollbar::Util.truncate(value, threshold)
34
36
  else
35
37
  value
@@ -2,6 +2,10 @@ require 'rollbar/util/hash'
2
2
 
3
3
  module Rollbar
4
4
  module Util # :nodoc:
5
+ def self.iterate_and_update_with_block(obj, &block)
6
+ iterate_and_update(obj, block)
7
+ end
8
+
5
9
  def self.iterate_and_update(obj, block, seen = {})
6
10
  return if obj.frozen? || seen[obj.object_id]
7
11
 
@@ -1,3 +1,3 @@
1
1
  module Rollbar
2
- VERSION = '2.22.1'.freeze
2
+ VERSION = '2.23.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rollbar
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.22.1
4
+ version: 2.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rollbar, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-30 00:00:00.000000000 Z
11
+ date: 2019-12-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Easy and powerful exception tracking for Ruby
14
14
  email:
@@ -95,6 +95,7 @@ files:
95
95
  - lib/rollbar/plugins/delayed_job.rb
96
96
  - lib/rollbar/plugins/delayed_job/job_data.rb
97
97
  - lib/rollbar/plugins/delayed_job/plugin.rb
98
+ - lib/rollbar/plugins/error_context.rb
98
99
  - lib/rollbar/plugins/goalie.rb
99
100
  - lib/rollbar/plugins/rack.rb
100
101
  - lib/rollbar/plugins/rails.rb