rollbar 2.16.2 → 2.22.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (212) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +47 -0
  3. data/.travis.yml +182 -94
  4. data/Appraisals +10 -10
  5. data/Gemfile +45 -13
  6. data/README.md +20 -3
  7. data/Rakefile +0 -0
  8. data/data/rollbar.snippet.js +1 -1
  9. data/docs/configuration.md +15 -0
  10. data/gemfiles/rails30.gemfile +21 -14
  11. data/gemfiles/rails31.gemfile +21 -12
  12. data/gemfiles/rails32.gemfile +18 -8
  13. data/gemfiles/rails40.gemfile +18 -6
  14. data/gemfiles/rails41.gemfile +17 -6
  15. data/gemfiles/rails42.gemfile +24 -14
  16. data/gemfiles/rails50.gemfile +20 -11
  17. data/gemfiles/rails51.gemfile +20 -10
  18. data/gemfiles/rails52.gemfile +65 -0
  19. data/gemfiles/rails60.gemfile +67 -0
  20. data/lib/generators/rollbar/rollbar_generator.rb +1 -1
  21. data/lib/rails/rollbar_runner.rb +17 -2
  22. data/lib/rollbar.rb +2 -3
  23. data/lib/rollbar/capistrano.rb +71 -39
  24. data/lib/rollbar/capistrano3.rb +56 -1
  25. data/lib/rollbar/capistrano_tasks.rb +130 -0
  26. data/lib/rollbar/configuration.rb +95 -7
  27. data/lib/rollbar/delay/active_job.rb +17 -0
  28. data/lib/rollbar/delay/girl_friday.rb +2 -2
  29. data/lib/rollbar/delay/resque.rb +4 -6
  30. data/lib/rollbar/delay/shoryuken.rb +15 -9
  31. data/lib/rollbar/delay/sidekiq.rb +6 -8
  32. data/lib/rollbar/delay/sucker_punch.rb +17 -19
  33. data/lib/rollbar/delay/thread.rb +3 -3
  34. data/lib/rollbar/deploy.rb +90 -0
  35. data/lib/rollbar/encoding/encoder.rb +9 -9
  36. data/lib/rollbar/exception_reporter.rb +19 -5
  37. data/lib/rollbar/item.rb +62 -20
  38. data/lib/rollbar/item/backtrace.rb +4 -4
  39. data/lib/rollbar/item/frame.rb +7 -1
  40. data/lib/rollbar/item/locals.rb +56 -0
  41. data/lib/rollbar/json.rb +5 -51
  42. data/lib/rollbar/language_support.rb +4 -20
  43. data/lib/rollbar/lazy_store.rb +5 -5
  44. data/lib/rollbar/logger.rb +1 -0
  45. data/lib/rollbar/logger_proxy.rb +15 -2
  46. data/lib/rollbar/middleware/js.rb +110 -10
  47. data/lib/rollbar/middleware/js/json_value.rb +26 -0
  48. data/lib/rollbar/middleware/rack.rb +4 -1
  49. data/lib/rollbar/middleware/rails/rollbar.rb +10 -1
  50. data/lib/rollbar/notifier.rb +118 -49
  51. data/lib/rollbar/notifier/trace_with_bindings.rb +65 -0
  52. data/lib/rollbar/plugin.rb +54 -6
  53. data/lib/rollbar/plugins.rb +7 -1
  54. data/lib/rollbar/plugins/active_job.rb +5 -1
  55. data/lib/rollbar/plugins/basic_socket.rb +21 -6
  56. data/lib/rollbar/plugins/delayed_job/job_data.rb +3 -3
  57. data/lib/rollbar/plugins/delayed_job/plugin.rb +3 -3
  58. data/lib/rollbar/plugins/goalie.rb +11 -3
  59. data/lib/rollbar/plugins/rails/controller_methods.rb +17 -4
  60. data/lib/rollbar/plugins/rails/railtie_mixin.rb +7 -3
  61. data/lib/rollbar/plugins/rake.rb +2 -2
  62. data/lib/rollbar/plugins/sidekiq/plugin.rb +10 -6
  63. data/lib/rollbar/rake_tasks.rb +3 -86
  64. data/lib/rollbar/request_data_extractor.rb +35 -21
  65. data/lib/rollbar/rollbar_test.rb +147 -0
  66. data/lib/rollbar/scrubbers.rb +7 -3
  67. data/lib/rollbar/scrubbers/params.rb +38 -20
  68. data/lib/rollbar/scrubbers/url.rb +27 -13
  69. data/lib/rollbar/truncation.rb +9 -2
  70. data/lib/rollbar/truncation/min_body_strategy.rb +2 -3
  71. data/lib/rollbar/truncation/remove_any_key_strategy.rb +123 -0
  72. data/lib/rollbar/truncation/remove_extra_strategy.rb +35 -0
  73. data/lib/rollbar/truncation/remove_request_strategy.rb +21 -0
  74. data/lib/rollbar/truncation/strings_strategy.rb +3 -4
  75. data/lib/rollbar/util.rb +75 -45
  76. data/lib/rollbar/util/hash.rb +30 -6
  77. data/lib/rollbar/util/ip_anonymizer.rb +8 -7
  78. data/lib/rollbar/util/ip_obfuscator.rb +1 -1
  79. data/lib/rollbar/version.rb +1 -1
  80. data/lib/tasks/benchmark.rake +103 -0
  81. data/rollbar.gemspec +14 -8
  82. metadata +25 -277
  83. data/gemfiles/ruby_1_8_and_1_9_2.gemfile +0 -49
  84. data/lib/rollbar/json/default.rb +0 -11
  85. data/lib/rollbar/json/oj.rb +0 -16
  86. data/lib/rollbar/tasks/rollbar.cap +0 -47
  87. data/spec/cacert.pem +0 -3988
  88. data/spec/controllers/home_controller_spec.rb +0 -480
  89. data/spec/delay/sidekiq_spec.rb +0 -61
  90. data/spec/delay/sucker_punch_spec.rb +0 -25
  91. data/spec/delayed/backend/test.rb +0 -140
  92. data/spec/delayed/serialization/test.rb +0 -0
  93. data/spec/dummyapp/.gitignore +0 -73
  94. data/spec/dummyapp/Rakefile +0 -7
  95. data/spec/dummyapp/app/assets/javascripts/application.js +0 -3
  96. data/spec/dummyapp/app/assets/stylesheets/application.css.scss +0 -37
  97. data/spec/dummyapp/app/controllers/application_controller.rb +0 -3
  98. data/spec/dummyapp/app/controllers/home_controller.rb +0 -60
  99. data/spec/dummyapp/app/controllers/users_controller.rb +0 -17
  100. data/spec/dummyapp/app/helpers/.gitkeep +0 -0
  101. data/spec/dummyapp/app/mailers/.gitkeep +0 -0
  102. data/spec/dummyapp/app/models/.gitkeep +0 -0
  103. data/spec/dummyapp/app/models/book.rb +0 -5
  104. data/spec/dummyapp/app/models/post.rb +0 -9
  105. data/spec/dummyapp/app/models/user.rb +0 -9
  106. data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +0 -27
  107. data/spec/dummyapp/app/views/devise/registrations/new.html.erb +0 -20
  108. data/spec/dummyapp/app/views/devise/shared/_links.html.erb +0 -25
  109. data/spec/dummyapp/app/views/home/cause_exception.html.erb +0 -1
  110. data/spec/dummyapp/app/views/home/index.html.erb +0 -4
  111. data/spec/dummyapp/app/views/home/report_exception.html.erb +0 -1
  112. data/spec/dummyapp/app/views/js/test.html.erb +0 -1
  113. data/spec/dummyapp/app/views/layouts/_messages.html.erb +0 -5
  114. data/spec/dummyapp/app/views/layouts/_navigation.html.erb +0 -21
  115. data/spec/dummyapp/app/views/layouts/application.html.erb +0 -25
  116. data/spec/dummyapp/app/views/layouts/simple.html.erb +0 -18
  117. data/spec/dummyapp/app/views/users/index.html.erb +0 -8
  118. data/spec/dummyapp/app/views/users/show.html.erb +0 -3
  119. data/spec/dummyapp/config.ru +0 -4
  120. data/spec/dummyapp/config/application.rb +0 -59
  121. data/spec/dummyapp/config/boot.rb +0 -10
  122. data/spec/dummyapp/config/database.yml +0 -25
  123. data/spec/dummyapp/config/environment.rb +0 -5
  124. data/spec/dummyapp/config/environments/development.rb +0 -37
  125. data/spec/dummyapp/config/environments/production.rb +0 -67
  126. data/spec/dummyapp/config/environments/test.rb +0 -37
  127. data/spec/dummyapp/config/initializers/backtrace_silencers.rb +0 -7
  128. data/spec/dummyapp/config/initializers/inflections.rb +0 -15
  129. data/spec/dummyapp/config/initializers/mime_types.rb +0 -5
  130. data/spec/dummyapp/config/initializers/rollbar.rb +0 -26
  131. data/spec/dummyapp/config/initializers/secret_token.rb +0 -7
  132. data/spec/dummyapp/config/initializers/session_store.rb +0 -8
  133. data/spec/dummyapp/config/initializers/wrap_parameters.rb +0 -16
  134. data/spec/dummyapp/config/locales/devise.en.yml +0 -58
  135. data/spec/dummyapp/config/locales/en.yml +0 -5
  136. data/spec/dummyapp/config/routes.rb +0 -17
  137. data/spec/dummyapp/config/secrets.yml +0 -2
  138. data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +0 -46
  139. data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +0 -5
  140. data/spec/dummyapp/db/migrate/20161219184410_create_books.rb +0 -10
  141. data/spec/dummyapp/db/migrate/20161219185529_add_username_to_users.rb +0 -5
  142. data/spec/dummyapp/db/schema.rb +0 -41
  143. data/spec/dummyapp/db/seeds.rb +0 -12
  144. data/spec/dummyapp/lib/assets/.gitkeep +0 -0
  145. data/spec/dummyapp/public/404.html +0 -26
  146. data/spec/dummyapp/public/422.html +0 -26
  147. data/spec/dummyapp/public/500.html +0 -25
  148. data/spec/dummyapp/public/favicon.ico +0 -0
  149. data/spec/dummyapp/script/rails +0 -6
  150. data/spec/fixtures/file1 +0 -1
  151. data/spec/fixtures/file2 +0 -1
  152. data/spec/fixtures/payloads/message.json +0 -25
  153. data/spec/fixtures/payloads/sample.trace.json +0 -275
  154. data/spec/fixtures/payloads/sample.trace_chain.json +0 -530
  155. data/spec/fixtures/plugins/dummy1.rb +0 -5
  156. data/spec/fixtures/plugins/dummy2.rb +0 -5
  157. data/spec/generators/rollbar/rollbar_generator_rails30_spec.rb +0 -31
  158. data/spec/generators/rollbar/rollbar_generator_spec.rb +0 -51
  159. data/spec/requests/home_spec.rb +0 -49
  160. data/spec/rollbar/configuration_spec.rb +0 -46
  161. data/spec/rollbar/delay/delayed_job_spec.rb +0 -22
  162. data/spec/rollbar/delay/girl_friday_spec.rb +0 -41
  163. data/spec/rollbar/delay/resque_spec.rb +0 -37
  164. data/spec/rollbar/delay/thread_spec.rb +0 -27
  165. data/spec/rollbar/encoding/encoder_spec.rb +0 -63
  166. data/spec/rollbar/item/backtrace_spec.rb +0 -26
  167. data/spec/rollbar/item/frame_spec.rb +0 -267
  168. data/spec/rollbar/item_spec.rb +0 -736
  169. data/spec/rollbar/json/oj_spec.rb +0 -18
  170. data/spec/rollbar/json_spec.rb +0 -110
  171. data/spec/rollbar/lazy_store_spec.rb +0 -99
  172. data/spec/rollbar/logger_proxy_spec.rb +0 -50
  173. data/spec/rollbar/logger_spec.rb +0 -124
  174. data/spec/rollbar/middleware/js_spec.rb +0 -421
  175. data/spec/rollbar/middleware/sinatra_spec.rb +0 -197
  176. data/spec/rollbar/notifier_spec.rb +0 -56
  177. data/spec/rollbar/plugin_spec.rb +0 -209
  178. data/spec/rollbar/plugins/active_job_spec.rb +0 -38
  179. data/spec/rollbar/plugins/delayed_job/job_data_spec.rb +0 -48
  180. data/spec/rollbar/plugins/delayed_job_spec.rb +0 -129
  181. data/spec/rollbar/plugins/rack_spec.rb +0 -152
  182. data/spec/rollbar/plugins/rails_js_spec.rb +0 -19
  183. data/spec/rollbar/plugins/rake_spec.rb +0 -34
  184. data/spec/rollbar/plugins/resque/failure_spec.rb +0 -36
  185. data/spec/rollbar/plugins/sidekiq_spec.rb +0 -171
  186. data/spec/rollbar/plugins/validations_spec.rb +0 -56
  187. data/spec/rollbar/plugins_spec.rb +0 -68
  188. data/spec/rollbar/request_data_extractor_spec.rb +0 -270
  189. data/spec/rollbar/scrubbers/params_spec.rb +0 -314
  190. data/spec/rollbar/scrubbers/url_spec.rb +0 -136
  191. data/spec/rollbar/scrubbers_spec.rb +0 -31
  192. data/spec/rollbar/sidekig/clear_scope_spec.rb +0 -19
  193. data/spec/rollbar/truncation/frames_strategy_spec.rb +0 -70
  194. data/spec/rollbar/truncation/min_body_strategy_spec.rb +0 -57
  195. data/spec/rollbar/truncation/strings_strategy_spec.rb +0 -89
  196. data/spec/rollbar/truncation_spec.rb +0 -27
  197. data/spec/rollbar/util/hash_spec.rb +0 -22
  198. data/spec/rollbar/util/ip_anonymizer_spec.rb +0 -30
  199. data/spec/rollbar/util_spec.rb +0 -80
  200. data/spec/rollbar_bc_spec.rb +0 -380
  201. data/spec/rollbar_spec.rb +0 -1667
  202. data/spec/spec_helper.rb +0 -84
  203. data/spec/support/cause_exception.rb +0 -1
  204. data/spec/support/encoding_helpers.rb +0 -8
  205. data/spec/support/encodings/iso_8859_9 +0 -1
  206. data/spec/support/fixture_helpers.rb +0 -10
  207. data/spec/support/get_ip_raising.rb +0 -7
  208. data/spec/support/helpers.rb +0 -5
  209. data/spec/support/matchers.rb +0 -23
  210. data/spec/support/notifier_helpers.rb +0 -57
  211. data/spec/support/rollbar_api.rb +0 -57
  212. data/spec/support/shared_contexts.rb +0 -12
@@ -17,12 +17,15 @@ module Rollbar
17
17
 
18
18
  Rollbar.scoped(fetch_scope(env)) do
19
19
  begin
20
+ Rollbar.notifier.enable_locals
20
21
  response = @app.call(env)
21
22
  report_exception_to_rollbar(env, framework_error(env)) if framework_error(env)
22
23
  response
23
24
  rescue Exception => e
24
25
  report_exception_to_rollbar(env, e)
25
26
  raise
27
+ ensure
28
+ Rollbar.notifier.disable_locals
26
29
  end
27
30
  end
28
31
  end
@@ -41,7 +44,7 @@ module Rollbar
41
44
  proc { extract_person_data_from_controller(env) }
42
45
  end
43
46
 
44
- def framework_error(env)
47
+ def framework_error(_env)
45
48
  nil
46
49
  end
47
50
  end
@@ -21,6 +21,7 @@ module Rollbar
21
21
 
22
22
  Rollbar.scoped(scope) do
23
23
  begin
24
+ Rollbar.notifier.enable_locals
24
25
  response = @app.call(env)
25
26
 
26
27
  if (framework_exception = env['action_dispatch.exception'])
@@ -31,6 +32,8 @@ module Rollbar
31
32
  rescue Exception => exception
32
33
  report_exception_to_rollbar(env, exception)
33
34
  raise
35
+ ensure
36
+ Rollbar.notifier.disable_locals
34
37
  end
35
38
  end
36
39
  end
@@ -62,7 +65,13 @@ module Rollbar
62
65
  block = proc { extract_person_data_from_controller(env) }
63
66
  return block unless defined?(ActiveRecord::Base) && ActiveRecord::Base.connected?
64
67
 
65
- proc { ActiveRecord::Base.connection_pool.with_connection(&block) }
68
+ proc do
69
+ begin
70
+ ActiveRecord::Base.connection_pool.with_connection(&block)
71
+ rescue ActiveRecord::ConnectionTimeoutError
72
+ {}
73
+ end
74
+ end
66
75
  end
67
76
 
68
77
  def context(request_data)
@@ -8,6 +8,7 @@ require 'rollbar/delay/girl_friday'
8
8
  require 'rollbar/delay/thread'
9
9
  require 'rollbar/logger_proxy'
10
10
  require 'rollbar/item'
11
+ require 'rollbar/notifier/trace_with_bindings'
11
12
  require 'ostruct'
12
13
 
13
14
  module Rollbar
@@ -41,21 +42,21 @@ module Rollbar
41
42
  # Similar to configure below, but used only internally within the gem
42
43
  # to configure it without initializing any of the third party hooks
43
44
  def preconfigure
44
- yield(configuration)
45
+ yield(configuration.configured_options)
45
46
  end
46
47
 
47
48
  # Configures the notifier instance
48
49
  def configure
49
50
  configuration.enabled = true if configuration.enabled.nil?
50
51
 
51
- yield(configuration)
52
+ yield(configuration.configured_options)
52
53
  end
53
54
 
54
55
  def reconfigure
55
56
  self.configuration = Configuration.new
56
57
  configuration.enabled = true
57
58
 
58
- yield(configuration)
59
+ yield(configuration.configured_options)
59
60
  end
60
61
 
61
62
  def unconfigure
@@ -95,7 +96,7 @@ module Rollbar
95
96
  # @yield Block which exceptions won't be reported.
96
97
  def silenced
97
98
  yield
98
- rescue => e
99
+ rescue StandardError => e
99
100
  e.instance_variable_set(:@_rollbar_do_not_report, true)
100
101
  raise
101
102
  end
@@ -126,7 +127,7 @@ module Rollbar
126
127
  # Rollbar.log(e, 'This is a description of the exception')
127
128
  #
128
129
  def log(level, *args)
129
- return 'disabled' unless configuration.enabled
130
+ return 'disabled' unless enabled?
130
131
 
131
132
  message, exception, extra, context = extract_arguments(args)
132
133
  use_exception_level_filters = use_exception_level_filters?(extra)
@@ -134,10 +135,11 @@ module Rollbar
134
135
  return 'ignored' if ignored?(exception, use_exception_level_filters)
135
136
 
136
137
  begin
137
- call_before_process(:level => level,
138
- :exception => exception,
139
- :message => message,
140
- :extra => extra)
138
+ status = call_before_process(:level => level,
139
+ :exception => exception,
140
+ :message => message,
141
+ :extra => extra)
142
+ return 'ignored' if status == 'ignored'
141
143
  rescue Rollbar::Ignore
142
144
  return 'ignored'
143
145
  end
@@ -145,13 +147,19 @@ module Rollbar
145
147
  level = lookup_exception_level(level, exception,
146
148
  use_exception_level_filters)
147
149
 
148
- begin
149
- report(level, message, exception, extra, context)
150
- rescue StandardError, SystemStackError => e
151
- report_internal_error(e)
150
+ ret = report_with_rescue(level, message, exception, extra, context)
152
151
 
153
- 'error'
154
- end
152
+ raise(exception) if configuration.raise_on_error && exception
153
+
154
+ ret
155
+ end
156
+
157
+ def report_with_rescue(level, message, exception, extra, context)
158
+ report(level, message, exception, extra, context)
159
+ rescue StandardError, SystemStackError => e
160
+ report_internal_error(e)
161
+
162
+ 'error'
155
163
  end
156
164
 
157
165
  # See log() above
@@ -184,6 +192,11 @@ module Rollbar
184
192
  log('critical', *args)
185
193
  end
186
194
 
195
+ def enabled?
196
+ # Require access_token so we don't try to send events when unconfigured.
197
+ configuration.enabled && configuration.access_token && !configuration.access_token.empty?
198
+ end
199
+
187
200
  def process_item(item)
188
201
  if configuration.write_to_file
189
202
  if configuration.use_async
@@ -196,7 +209,7 @@ module Rollbar
196
209
  else
197
210
  send_item(item)
198
211
  end
199
- rescue => e
212
+ rescue StandardError => e
200
213
  log_error("[Rollbar] Error processing the item: #{e.class}, #{e.message}. Item: #{item.payload.inspect}")
201
214
  raise e
202
215
  end
@@ -235,7 +248,7 @@ module Rollbar
235
248
  Rollbar.silenced do
236
249
  begin
237
250
  process_item(item)
238
- rescue => e
251
+ rescue StandardError => e
239
252
  report_internal_error(e)
240
253
 
241
254
  raise
@@ -281,7 +294,7 @@ module Rollbar
281
294
  :configuration => configuration,
282
295
  :logger => logger)
283
296
  schedule_item(item)
284
- rescue => e
297
+ rescue StandardError => e
285
298
  log_error "[Rollbar] Error sending failsafe : #{e}"
286
299
  end
287
300
 
@@ -289,12 +302,40 @@ module Rollbar
289
302
  end
290
303
 
291
304
  ## Logging
292
- %w(debug info warn error).each do |level|
305
+ %w[debug info warn error].each do |level|
293
306
  define_method(:"log_#{level}") do |message|
294
307
  logger.send(level, message)
295
308
  end
296
309
  end
297
310
 
311
+ def logger
312
+ @logger ||= LoggerProxy.new(configuration.logger)
313
+ end
314
+
315
+ def trace_with_bindings
316
+ @trace_with_bindings ||= TraceWithBindings.new
317
+ end
318
+
319
+ def exception_bindings
320
+ trace_with_bindings.exception_frames
321
+ end
322
+
323
+ def current_bindings
324
+ trace_with_bindings.frames
325
+ end
326
+
327
+ def enable_locals?
328
+ configuration.locals[:enabled] && [:app, :all].include?(configuration.send_extra_frame_data)
329
+ end
330
+
331
+ def enable_locals
332
+ trace_with_bindings.enable if enable_locals?
333
+ end
334
+
335
+ def disable_locals
336
+ trace_with_bindings.disable if enable_locals?
337
+ end
338
+
298
339
  private
299
340
 
300
341
  def use_exception_level_filters?(options)
@@ -317,10 +358,11 @@ module Rollbar
317
358
 
318
359
  handlers.each do |handler|
319
360
  begin
320
- handler.call(options)
361
+ status = handler.call(options)
362
+ return 'ignored' if status == 'ignored'
321
363
  rescue Rollbar::Ignore
322
364
  raise
323
- rescue => e
365
+ rescue StandardError => e
324
366
  log_error("[Rollbar] Error calling the `before_process` hook: #{e}")
325
367
 
326
368
  break
@@ -339,14 +381,14 @@ module Rollbar
339
381
  message = arg
340
382
  elsif arg.is_a?(Exception)
341
383
  exception = arg
342
- elsif RUBY_PLATFORM == 'java' && arg.is_a?(java.lang.Exception)
384
+ elsif RUBY_PLATFORM == 'java' && arg.is_a?(java.lang.Throwable)
343
385
  exception = arg
344
386
  elsif arg.is_a?(Hash)
345
387
  extra = arg
346
-
388
+
347
389
  context = extra[:custom_data_method_context]
348
390
  extra.delete :custom_data_method_context
349
-
391
+
350
392
  extra = nil if extra.empty?
351
393
  end
352
394
  end
@@ -393,39 +435,53 @@ module Rollbar
393
435
 
394
436
  return 'ignored' if item.ignored?
395
437
 
396
- schedule_item(item)
438
+ schedule_item(item) if configuration.transmit
397
439
 
440
+ log_and_return_item_data(item)
441
+ end
442
+
443
+ def log_and_return_item_data(item)
398
444
  data = item['data']
399
445
  log_instance_link(data)
400
446
  Rollbar.last_report = data
447
+ log_data(data) if configuration.log_payload
401
448
 
402
449
  data
403
450
  end
404
451
 
452
+ def log_data(data)
453
+ log_info "[Rollbar] Data: #{data}"
454
+ end
455
+
405
456
  # Reports an internal error in the Rollbar library. This will be reported within the configured
406
457
  # Rollbar project. We'll first attempt to provide a report including the exception traceback.
407
458
  # If that fails, we'll fall back to a more static failsafe response.
408
459
  def report_internal_error(exception)
409
460
  log_error '[Rollbar] Reporting internal error encountered while sending data to Rollbar.'
410
461
 
462
+ configuration.execute_hook(:on_report_internal_error, exception)
463
+
411
464
  begin
412
465
  item = build_item('error', nil, exception, { :internal => true }, nil)
413
- rescue => e
466
+ rescue StandardError => e
414
467
  send_failsafe('build_item in exception_data', e)
468
+ log_error "[Rollbar] Exception: #{exception}"
415
469
  return
416
470
  end
417
471
 
418
472
  begin
419
473
  process_item(item)
420
- rescue => e
474
+ rescue StandardError => e
421
475
  send_failsafe('error in process_item', e)
476
+ log_error "[Rollbar] Item: #{item}"
422
477
  return
423
478
  end
424
479
 
425
480
  begin
426
481
  log_instance_link(item['data'])
427
- rescue => e
482
+ rescue StandardError => e
428
483
  send_failsafe('error logging instance link', e)
484
+ log_error "[Rollbar] Item: #{item}"
429
485
  return
430
486
  end
431
487
  end
@@ -501,19 +557,34 @@ module Rollbar
501
557
 
502
558
  if uri.scheme == 'https'
503
559
  http.use_ssl = true
504
- # This is needed to have 1.8.7 passing tests
505
- http.ca_file = ENV['ROLLBAR_SSL_CERT_FILE'] if ENV.key?('ROLLBAR_SSL_CERT_FILE')
506
560
  http.verify_mode = ssl_verify_mode
507
561
  end
508
562
 
509
563
  request = Net::HTTP::Post.new(uri.request_uri)
510
564
 
511
- request.body = body
565
+ request.body = pack_ruby260_bytes(body)
512
566
  request.add_field('X-Rollbar-Access-Token', access_token)
513
567
 
514
568
  handle_net_retries { http.request(request) }
515
569
  end
516
570
 
571
+ def pack_ruby260_bytes(body)
572
+ # Ruby 2.6.0 shipped with a bug affecting multi-byte body for Net::HTTP.
573
+ # Fix (committed one day after 2.6.0p0 shipped) is here:
574
+ # https://github.com/ruby/ruby/commit/1680a13a926b17661329beec1ded6b32aad16c1b#diff-00a99d8c71daaf5fc60a050da41f7261
575
+ #
576
+ # We work around this by repacking the body as single byte chars if needed.
577
+ if RUBY_VERSION == '2.6.0' && multibyte?(body)
578
+ body.unpack('C*').pack('C*')
579
+ else
580
+ body
581
+ end
582
+ end
583
+
584
+ def multibyte?(str)
585
+ str.chars.length != str.bytes.length
586
+ end
587
+
517
588
  def http_proxy_for_em(uri)
518
589
  proxy = http_proxy(uri)
519
590
  {
@@ -530,14 +601,15 @@ module Rollbar
530
601
  end
531
602
 
532
603
  def proxy_from_config
533
- proxy = configuration.proxy
534
- return nil unless proxy
604
+ proxy_settings = configuration.proxy
605
+ return nil unless proxy_settings
535
606
 
536
- px = URI.parse(proxy[:host])
537
- px.port = proxy[:port]
538
- px.user = proxy[:user]
539
- px.password = proxy[:password]
540
- px
607
+ proxy = null_proxy
608
+ proxy.host = URI.parse(proxy_settings[:host]).host
609
+ proxy.port = proxy_settings[:port]
610
+ proxy.user = proxy_settings[:user]
611
+ proxy.password = proxy_settings[:password]
612
+ proxy
541
613
  end
542
614
 
543
615
  def proxy_from_env(uri)
@@ -565,7 +637,7 @@ module Rollbar
565
637
  end
566
638
 
567
639
  def skip_retries?
568
- Rollbar::LanguageSupport.ruby_18? || Rollbar::LanguageSupport.ruby_19?
640
+ Rollbar::LanguageSupport.ruby_19?
569
641
  end
570
642
 
571
643
  def handle_response(response)
@@ -574,6 +646,7 @@ module Rollbar
574
646
  else
575
647
  log_warning "[Rollbar] Got unexpected status code from Rollbar api: #{response.code}"
576
648
  log_info "[Rollbar] Response: #{response.body}"
649
+ configuration.execute_hook(:on_error_response, response)
577
650
  end
578
651
  end
579
652
 
@@ -623,17 +696,17 @@ module Rollbar
623
696
 
624
697
  exception_info = exception.class.name
625
698
  # #to_s and #message defaults to class.to_s. Add message only if add valuable info.
626
- exception_info += %(: "#{exception.message}") if exception.message != exception.class.to_s
699
+ exception_info += %[: "#{exception.message}"] if exception.message != exception.class.to_s
627
700
  exception_info += " in #{nearest_frame}" if nearest_frame
628
701
 
629
702
  body += "#{exception_info}: #{message}"
630
- rescue
703
+ rescue StandardError
631
704
  log_error('[Rollbar] Error building failsafe exception message')
632
705
  end
633
706
  else
634
707
  begin
635
708
  body += message.to_s
636
- rescue
709
+ rescue StandardError
637
710
  log_error('[Rollbar] Error building failsafe message')
638
711
  end
639
712
  end
@@ -666,7 +739,7 @@ module Rollbar
666
739
  def process_async_item(item)
667
740
  configuration.async_handler ||= default_async_handler
668
741
  configuration.async_handler.call(item.payload)
669
- rescue
742
+ rescue StandardError
670
743
  if configuration.failover_handlers.empty?
671
744
  log_error '[Rollbar] Async handler failed, and there are no failover handlers configured. See the docs for "failover_handlers"'
672
745
  return
@@ -683,7 +756,7 @@ module Rollbar
683
756
  failover_handlers.each do |handler|
684
757
  begin
685
758
  handler.call(item.payload)
686
- rescue
759
+ rescue StandardError
687
760
  next unless handler == failover_handlers.last
688
761
 
689
762
  log_error "[Rollbar] All failover handlers failed while processing item: #{Rollbar::JSON.dump(item.payload)}"
@@ -691,7 +764,7 @@ module Rollbar
691
764
  end
692
765
  end
693
766
 
694
- alias_method :log_warning, :log_warn
767
+ alias log_warning log_warn
695
768
 
696
769
  def log_instance_link(data)
697
770
  return unless data[:uuid]
@@ -699,9 +772,5 @@ module Rollbar
699
772
  uuid_url = Util.uuid_rollbar_url(data, configuration)
700
773
  log_info "[Rollbar] Details: #{uuid_url} (only available if report was successful)"
701
774
  end
702
-
703
- def logger
704
- @logger ||= LoggerProxy.new(configuration.logger)
705
- end
706
775
  end
707
776
  end
@@ -0,0 +1,65 @@
1
+ module Rollbar
2
+ class Notifier
3
+ class TraceWithBindings # :nodoc:
4
+ attr_reader :frames, :exception_frames
5
+
6
+ def initialize
7
+ reset
8
+ end
9
+
10
+ def reset
11
+ @frames = []
12
+ @exception_frames = []
13
+ @exception_signature = nil
14
+ end
15
+
16
+ def enable
17
+ reset
18
+ trace_point.enable if defined?(TracePoint)
19
+ end
20
+
21
+ def disable
22
+ trace_point.disable if defined?(TracePoint)
23
+ end
24
+
25
+ private
26
+
27
+ def exception_signature(trace)
28
+ # use the exception backtrace to detect reraised exception.
29
+ trace.raised_exception.backtrace.first
30
+ end
31
+
32
+ def detect_reraise(trace)
33
+ @exception_signature == exception_signature(trace)
34
+ end
35
+
36
+ def trace_point
37
+ return unless defined?(TracePoint)
38
+
39
+ @trace_point ||= TracePoint.new(:call, :return, :b_call, :b_return, :c_call, :c_return, :raise) do |tp|
40
+ case tp.event
41
+ when :call, :b_call, :c_call, :class
42
+ frames.push frame(tp)
43
+ when :return, :b_return, :c_return, :end
44
+ frames.pop
45
+ when :raise
46
+ unless detect_reraise(tp) # ignore reraised exceptions
47
+ @exception_frames = @frames.dup # may be possible to optimize better than #dup
48
+ @exception_signature = exception_signature(tp)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def frame(trace)
55
+ {
56
+ :binding => trace.binding,
57
+ :defined_class => trace.defined_class,
58
+ :method_id => trace.method_id,
59
+ :path => trace.path,
60
+ :lineno => trace.lineno
61
+ }
62
+ end
63
+ end
64
+ end
65
+ end