rollbar 2.25.1 → 3.1.1

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.
@@ -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.unshift(trace_data(cause))
58
+ traces << trace_data(cause)
59
59
  visited << cause
60
60
  current_exception = cause
61
61
  end
@@ -10,10 +10,6 @@ module Rollbar
10
10
  mod.const_get(target, inherit)
11
11
  end
12
12
 
13
- def ruby_19?
14
- version?('1.9')
15
- end
16
-
17
13
  def version?(version)
18
14
  numbers = version.split('.')
19
15
 
@@ -21,8 +17,6 @@ module Rollbar
21
17
  end
22
18
 
23
19
  def timeout_exceptions
24
- return [] if ruby_19?
25
-
26
20
  [Net::ReadTimeout, Net::OpenTimeout]
27
21
  end
28
22
  end
@@ -41,8 +41,6 @@ module Rollbar
41
41
  raw[key] = value
42
42
 
43
43
  loaded_data.delete(key)
44
-
45
- value
46
44
  end
47
45
 
48
46
  def data
@@ -76,8 +74,8 @@ module Rollbar
76
74
  super
77
75
  end
78
76
 
79
- def respond_to?(method_sym)
80
- super || raw.respond_to?(method_sym)
77
+ def respond_to_missing?(method_sym, include_all)
78
+ raw.respond_to?(method_sym, include_all)
81
79
  end
82
80
  end
83
81
  end
@@ -80,8 +80,11 @@ module Rollbar
80
80
  return app_result unless response_string
81
81
 
82
82
  env[JS_IS_INJECTED_KEY] = true
83
- response = ::Rack::Response.new(response_string, app_result[0],
84
- app_result[1])
83
+
84
+ status, headers, = app_result
85
+ headers['Content-Length'] = response_string.bytesize.to_s if headers.key?('Content-Length')
86
+
87
+ response = ::Rack::Response.new(response_string, status, headers)
85
88
 
86
89
  finished = response.finish
87
90
 
@@ -21,6 +21,7 @@ module Rollbar
21
21
 
22
22
  MUTEX = Mutex.new
23
23
  EXTENSION_REGEXP = /.rollbar\z/.freeze
24
+ FAILSAFE_STRING_LENGTH = 10_000
24
25
 
25
26
  def initialize(parent_notifier = nil, payload_options = nil, scope = nil)
26
27
  if parent_notifier
@@ -158,7 +159,13 @@ module Rollbar
158
159
  def report_with_rescue(level, message, exception, extra, context)
159
160
  report(level, message, exception, extra, context)
160
161
  rescue StandardError, SystemStackError => e
161
- report_internal_error(e)
162
+ original_error = {
163
+ :message => message,
164
+ :exception => exception,
165
+ :configuration => configuration
166
+ }
167
+
168
+ report_internal_error(e, original_error)
162
169
 
163
170
  'error'
164
171
  end
@@ -262,32 +269,32 @@ module Rollbar
262
269
  end
263
270
  end
264
271
 
265
- def send_failsafe(message, exception, uuid = nil, host = nil)
266
- exception_reason = failsafe_reason(message, exception)
267
-
268
- log_error "[Rollbar] Sending failsafe response due to #{exception_reason}"
269
-
270
- body = failsafe_body(exception_reason)
271
-
272
- failsafe_data = {
272
+ def failsafe_initial_data(exception_reason)
273
+ {
273
274
  :level => 'error',
274
275
  :environment => configuration.environment.to_s,
275
276
  :body => {
276
277
  :message => {
277
- :body => body
278
+ :body => failsafe_body(exception_reason)
278
279
  }
279
280
  },
280
281
  :notifier => {
281
282
  :name => 'rollbar-gem',
282
283
  :version => VERSION
283
284
  },
284
- :custom => {
285
- :orig_uuid => uuid,
286
- :orig_host => host
287
- },
288
285
  :internal => true,
289
286
  'failsafe' => true
290
287
  }
288
+ end
289
+
290
+ def send_failsafe(message, exception, original_error = nil)
291
+ exception_reason = failsafe_reason(message, exception)
292
+
293
+ log_error "[Rollbar] Sending failsafe response due to #{exception_reason}"
294
+
295
+ failsafe_data = failsafe_initial_data(exception_reason)
296
+
297
+ failsafe_add_original_error_data(failsafe_data[:notifier], original_error)
291
298
 
292
299
  failsafe_payload = {
293
300
  'data' => failsafe_data
@@ -298,7 +305,9 @@ module Rollbar
298
305
  :notifier => self,
299
306
  :configuration => configuration,
300
307
  :logger => logger)
301
- schedule_item(item)
308
+
309
+ process_item(item)
310
+ log_and_return_item_data(item)
302
311
  rescue StandardError => e
303
312
  log_error "[Rollbar] Error sending failsafe : #{e}"
304
313
  end
@@ -306,6 +315,57 @@ module Rollbar
306
315
  failsafe_payload
307
316
  end
308
317
 
318
+ def failsafe_add_original_error_data(payload_notifier, original_error)
319
+ return unless original_error
320
+
321
+ payload_notifier[:diagnostic] ||= {}
322
+
323
+ add_original_host(payload_notifier[:diagnostic], original_error)
324
+ add_original_uuid(payload_notifier[:diagnostic], original_error)
325
+ add_original_message(payload_notifier[:diagnostic], original_error)
326
+ add_original_error(payload_notifier[:diagnostic], original_error)
327
+ add_configured_options(payload_notifier, original_error)
328
+ end
329
+
330
+ def add_original_message(diagnostic, original_error)
331
+ diagnostic[:original_message] = original_error[:message].truncate(FAILSAFE_STRING_LENGTH) if original_error[:message]
332
+
333
+ rescue StandardError => e
334
+ diagnostic[:original_message] = "Failed: #{e.message}"
335
+ end
336
+
337
+ def add_original_error(diagnostic, original_error)
338
+ if original_error[:exception]
339
+ backtrace = original_error[:exception].backtrace
340
+ message = original_error[:exception].message
341
+ diagnostic[:original_error] = {
342
+ :message => message && message.truncate(FAILSAFE_STRING_LENGTH),
343
+ :stack => backtrace && backtrace.join(', ').truncate(FAILSAFE_STRING_LENGTH)
344
+ }
345
+ end
346
+
347
+ rescue StandardError => e
348
+ diagnostic[:original_error] = "Failed: #{e.message}"
349
+ end
350
+
351
+ def add_configured_options(payload_notifier, original_error)
352
+ if original_error[:configuration]
353
+ configured = original_error[:configuration].configured_options.configured
354
+ payload_notifier[:configured_options] = ::JSON.generate(configured).truncate(FAILSAFE_STRING_LENGTH)
355
+ end
356
+
357
+ rescue StandardError => e
358
+ payload_notifier[:configured_options] = "Failed: #{e.message}"
359
+ end
360
+
361
+ def add_original_host(diagnostic, original_error)
362
+ diagnostic[:original_host] = original_error[:host] if original_error[:host]
363
+ end
364
+
365
+ def add_original_uuid(diagnostic, original_error)
366
+ diagnostic[:original_uuid] = original_error[:uuid] if original_error[:uuid]
367
+ end
368
+
309
369
  ## Logging
310
370
  %w[debug info warn error].each do |level|
311
371
  define_method(:"log_#{level}") do |message|
@@ -461,7 +521,7 @@ module Rollbar
461
521
  # Reports an internal error in the Rollbar library. This will be reported within the configured
462
522
  # Rollbar project. We'll first attempt to provide a report including the exception traceback.
463
523
  # If that fails, we'll fall back to a more static failsafe response.
464
- def report_internal_error(exception)
524
+ def report_internal_error(exception, original_error = nil)
465
525
  log_error '[Rollbar] Reporting internal error encountered while sending data to Rollbar.'
466
526
 
467
527
  configuration.execute_hook(:on_report_internal_error, exception)
@@ -469,7 +529,7 @@ module Rollbar
469
529
  begin
470
530
  item = build_item('error', nil, exception, { :internal => true }, nil)
471
531
  rescue StandardError => e
472
- send_failsafe('build_item in exception_data', e)
532
+ send_failsafe('build_item in exception_data', e, original_error)
473
533
  log_error "[Rollbar] Exception: #{exception}"
474
534
  return
475
535
  end
@@ -477,7 +537,7 @@ module Rollbar
477
537
  begin
478
538
  process_item(item)
479
539
  rescue StandardError => e
480
- send_failsafe('error in process_item', e)
540
+ send_failsafe('error in process_item', e, original_error)
481
541
  log_error "[Rollbar] Item: #{item}"
482
542
  return
483
543
  end
@@ -485,7 +545,7 @@ module Rollbar
485
545
  begin
486
546
  log_instance_link(item['data'])
487
547
  rescue StandardError => e
488
- send_failsafe('error logging instance link', e)
548
+ send_failsafe('error logging instance link', e, original_error)
489
549
  log_error "[Rollbar] Item: #{item}"
490
550
  return
491
551
  end
@@ -580,7 +640,11 @@ module Rollbar
580
640
  request = Net::HTTP::Post.new(uri.request_uri)
581
641
 
582
642
  request.body = pack_ruby260_bytes(body)
583
- request.add_field('X-Rollbar-Access-Token', access_token)
643
+
644
+ # Ensure the payload token will be used if the option is set.
645
+ unless (configuration.use_payload_access_token)
646
+ request.add_field('X-Rollbar-Access-Token', access_token)
647
+ end
584
648
 
585
649
  handle_net_retries { http.request(request) }
586
650
  end
@@ -638,8 +702,6 @@ module Rollbar
638
702
  end
639
703
 
640
704
  def handle_net_retries
641
- return yield if skip_retries?
642
-
643
705
  retries = configuration.net_retries - 1
644
706
 
645
707
  begin
@@ -653,10 +715,6 @@ module Rollbar
653
715
  end
654
716
  end
655
717
 
656
- def skip_retries?
657
- Rollbar::LanguageSupport.ruby_19?
658
- end
659
-
660
718
  def handle_response(response)
661
719
  if response.code == '200'
662
720
  log_info '[Rollbar] Success'
@@ -60,6 +60,10 @@ module Rollbar
60
60
  end
61
61
 
62
62
  def self.skip_report?(job)
63
+ handler = ::Rollbar.configuration.async_skip_report_handler
64
+
65
+ return handler.call(job) if handler.respond_to?(:call)
66
+
63
67
  job.attempts < ::Rollbar.configuration.dj_threshold
64
68
  end
65
69
 
@@ -1,6 +1,6 @@
1
1
 
2
2
  namespace :rollbar do
3
- desc 'Verify your gem installation by sending a test exception to Rollbar'
3
+ desc 'Verify your gem installation by sending a test message to Rollbar'
4
4
  task :test => [:environment] do
5
5
  rollbar_dir = Gem.loaded_specs['rollbar'].full_gem_path
6
6
  require "#{rollbar_dir}/lib/rollbar/rollbar_test"
@@ -131,6 +131,7 @@ module Rollbar
131
131
  host = host.split(',').first.strip unless host.empty?
132
132
 
133
133
  path = env['ORIGINAL_FULLPATH'] || env['REQUEST_URI']
134
+ path ||= "#{env['SCRIPT_NAME']}#{env['PATH_INFO']}#{"?#{env['QUERY_STRING']}" unless env['QUERY_STRING'].to_s.empty?}"
134
135
  unless path.nil? || path.empty?
135
136
  path = '/' + path.to_s if path.to_s.slice(0, 1) != '/'
136
137
  end
@@ -1,48 +1,16 @@
1
1
  require 'rollbar'
2
- begin
3
- require 'rack/mock'
4
- rescue LoadError
5
- puts 'Cannot load rack/mock'
6
- end
7
- require 'logger'
8
2
 
9
- # Module to inject into the Rails controllers or rack apps
10
3
  module RollbarTest # :nodoc:
11
- def test_rollbar
12
- puts 'Raising RollbarTestingException to simulate app failure.'
13
-
14
- raise RollbarTestingException.new, ::RollbarTest.success_message
15
- end
16
-
17
4
  def self.run
18
5
  return unless confirmed_token?
19
6
 
20
- configure_rails if defined?(Rails)
21
-
22
- puts 'Testing manual report...'
23
- Rollbar.error('Test error from rollbar:test')
24
-
25
- return unless defined?(Rack::MockRequest)
26
-
27
- protocol, app = setup_app
28
-
29
- puts 'Processing...'
30
- env = Rack::MockRequest.env_for("#{protocol}://www.example.com/verify", 'REMOTE_ADDR' => '127.0.0.1')
31
- status, = app.call(env)
32
-
33
- puts error_message unless status.to_i == 500
34
- end
35
-
36
- def self.configure_rails
37
- Rails.logger = if defined?(ActiveSupport::TaggedLogging)
38
- ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
39
- else
40
- Logger.new(STDOUT)
41
- end
7
+ puts 'Test sending to Rollbar...'
8
+ result = Rollbar.info('Test message from rollbar:test')
42
9
 
43
- Rails.logger.level = Logger::DEBUG
44
- Rollbar.preconfigure do |config|
45
- config.logger = Rails.logger
10
+ if result == 'error'
11
+ puts error_message
12
+ else
13
+ puts success_message
46
14
  end
47
15
  end
48
16
 
@@ -54,69 +22,6 @@ module RollbarTest # :nodoc:
54
22
  false
55
23
  end
56
24
 
57
- def self.authlogic_config
58
- # from http://stackoverflow.com/questions/5270835/authlogic-activation-problems
59
- return unless defined?(Authlogic)
60
-
61
- Authlogic::Session::Base.controller = Authlogic::ControllerAdapters::RailsAdapter.new(self)
62
- end
63
-
64
- def self.setup_app
65
- puts 'Setting up the test app.'
66
-
67
- if defined?(Rails)
68
- app = rails_app
69
-
70
- draw_rails_route(app)
71
-
72
- authlogic_config
73
-
74
- [rails_protocol(app), app]
75
- else
76
- ['http', rack_app]
77
- end
78
- end
79
-
80
- def self.rails_app
81
- # The setup below is needed for Rails 5.x, but not for Rails 4.x and below.
82
- # (And fails on Rails 4.x in various ways depending on the exact version.)
83
- return Rails.application if Rails.version < '5.0.0'
84
-
85
- # Spring now runs by default in development on all new Rails installs. This causes
86
- # the new `/verify` route to not get picked up if `config.cache_classes == false`
87
- # which is also a default in development env.
88
- #
89
- # `config.cache_classes` needs to be set, but the only possible time is at app load,
90
- # so here we clone the default app with an updated config.
91
- #
92
- config = Rails.application.config
93
- config.cache_classes = true
94
-
95
- # Make a copy of the app, so the config can be updated.
96
- Rails.application.class.name.constantize.new(:config => config)
97
- end
98
-
99
- def self.draw_rails_route(app)
100
- app.routes_reloader.execute_if_updated
101
- app.routes.draw do
102
- get 'verify' => 'rollbar_test#verify', :as => 'verify'
103
- end
104
- end
105
-
106
- def self.rails_protocol(app)
107
- defined?(app.config.force_ssl && app.config.force_ssl) ? 'https' : 'http'
108
- end
109
-
110
- def self.rack_app
111
- Class.new do
112
- include RollbarTest
113
-
114
- def self.call(_env)
115
- new.test_rollbar
116
- end
117
- end
118
- end
119
-
120
25
  def self.token_error_message
121
26
  'Rollbar needs an access token configured. Check the README for instructions.'
122
27
  end
@@ -129,19 +34,3 @@ module RollbarTest # :nodoc:
129
34
  'Testing rollbar with "rake rollbar:test". If you can see this, it works.'
130
35
  end
131
36
  end
132
-
133
- class RollbarTestingException < RuntimeError; end
134
-
135
- if defined?(Rails)
136
- class RollbarTestController < ActionController::Base # :nodoc:
137
- include RollbarTest
138
-
139
- def verify
140
- test_rollbar
141
- end
142
-
143
- def logger
144
- nil
145
- end
146
- end
147
- end
@@ -67,10 +67,7 @@ module Rollbar
67
67
 
68
68
  params = decode_www_form(query)
69
69
 
70
- encoded_query = encode_www_form(filter_query_params(params, regex, randomize_scrub_length, scrub_all, whitelist))
71
-
72
- # We want this to rebuild array params like foo[]=1&foo[]=2
73
- URI.escape(CGI.unescape(encoded_query))
70
+ encode_www_form(filter_query_params(params, regex, randomize_scrub_length, scrub_all, whitelist))
74
71
  end
75
72
 
76
73
  def decode_www_form(query)
@@ -78,7 +75,15 @@ module Rollbar
78
75
  end
79
76
 
80
77
  def encode_www_form(params)
81
- URI.encode_www_form(params)
78
+ restore_square_brackets(URI.encode_www_form(params))
79
+ end
80
+
81
+ def restore_square_brackets(query)
82
+ # We want this to rebuild array params like foo[]=1&foo[]=2
83
+ #
84
+ # URI.encode_www_form follows the spec at https://url.spec.whatwg.org/#concept-urlencoded-serializer
85
+ # and percent encodes square brackets. Here we change them back.
86
+ query.gsub('%5B', '[').gsub('%5D', ']')
82
87
  end
83
88
 
84
89
  def filter_query_params(params, regex, randomize_scrub_length, scrub_all, whitelist)