rollbar 2.19.1 → 2.27.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.
Files changed (86) hide show
  1. checksums.yaml +5 -5
  2. data/.github/pull_request_template.md +25 -0
  3. data/.rubocop.yml +168 -0
  4. data/.travis.yml +63 -34
  5. data/Appraisals +10 -10
  6. data/Gemfile +35 -14
  7. data/README.md +5 -2
  8. data/Rakefile +0 -0
  9. data/data/rollbar.snippet.js +1 -1
  10. data/docs/configuration.md +17 -0
  11. data/gemfiles/rails30.gemfile +10 -10
  12. data/gemfiles/rails31.gemfile +10 -9
  13. data/gemfiles/rails32.gemfile +10 -9
  14. data/gemfiles/rails40.gemfile +10 -9
  15. data/gemfiles/rails41.gemfile +10 -9
  16. data/gemfiles/rails42.gemfile +12 -9
  17. data/gemfiles/rails50.gemfile +21 -14
  18. data/gemfiles/rails51.gemfile +21 -14
  19. data/gemfiles/rails52.gemfile +15 -12
  20. data/gemfiles/rails60.gemfile +67 -0
  21. data/lib/generators/rollbar/rollbar_generator.rb +1 -1
  22. data/lib/rails/rollbar_runner.rb +4 -2
  23. data/lib/rollbar/capistrano.rb +1 -1
  24. data/lib/rollbar/capistrano3.rb +6 -3
  25. data/lib/rollbar/capistrano_tasks.rb +29 -21
  26. data/lib/rollbar/configuration.rb +86 -16
  27. data/lib/rollbar/delay/girl_friday.rb +4 -8
  28. data/lib/rollbar/delay/resque.rb +3 -6
  29. data/lib/rollbar/delay/sidekiq.rb +4 -10
  30. data/lib/rollbar/delay/sucker_punch.rb +16 -19
  31. data/lib/rollbar/delay/thread.rb +16 -2
  32. data/lib/rollbar/deploy.rb +52 -29
  33. data/lib/rollbar/encoding/encoder.rb +17 -10
  34. data/lib/rollbar/exception_reporter.rb +19 -5
  35. data/lib/rollbar/item/backtrace.rb +13 -3
  36. data/lib/rollbar/item/frame.rb +9 -1
  37. data/lib/rollbar/item/locals.rb +100 -0
  38. data/lib/rollbar/item.rb +56 -17
  39. data/lib/rollbar/json.rb +6 -51
  40. data/lib/rollbar/language_support.rb +4 -20
  41. data/lib/rollbar/lazy_store.rb +5 -5
  42. data/lib/rollbar/logger.rb +1 -0
  43. data/lib/rollbar/logger_proxy.rb +6 -2
  44. data/lib/rollbar/middleware/js.rb +28 -18
  45. data/lib/rollbar/middleware/rack.rb +4 -1
  46. data/lib/rollbar/middleware/rails/rollbar.rb +10 -1
  47. data/lib/rollbar/notifier/trace_with_bindings.rb +65 -0
  48. data/lib/rollbar/notifier.rb +225 -89
  49. data/lib/rollbar/plugin.rb +54 -6
  50. data/lib/rollbar/plugins/active_job.rb +6 -2
  51. data/lib/rollbar/plugins/basic_socket.rb +21 -6
  52. data/lib/rollbar/plugins/delayed_job/job_data.rb +3 -3
  53. data/lib/rollbar/plugins/delayed_job/plugin.rb +13 -3
  54. data/lib/rollbar/plugins/error_context.rb +11 -0
  55. data/lib/rollbar/plugins/goalie.rb +11 -3
  56. data/lib/rollbar/plugins/rails/controller_methods.rb +15 -3
  57. data/lib/rollbar/plugins/rake.rb +2 -2
  58. data/lib/rollbar/plugins/sidekiq/plugin.rb +5 -4
  59. data/lib/rollbar/plugins.rb +7 -1
  60. data/lib/rollbar/rake_tasks.rb +4 -148
  61. data/lib/rollbar/request_data_extractor.rb +31 -21
  62. data/lib/rollbar/rollbar_test.rb +36 -0
  63. data/lib/rollbar/scrubbers/params.rb +19 -18
  64. data/lib/rollbar/scrubbers/url.rb +18 -9
  65. data/lib/rollbar/scrubbers.rb +3 -3
  66. data/lib/rollbar/truncation/frames_strategy.rb +1 -1
  67. data/lib/rollbar/truncation/min_body_strategy.rb +2 -3
  68. data/lib/rollbar/truncation/mixin.rb +1 -1
  69. data/lib/rollbar/truncation/remove_any_key_strategy.rb +123 -0
  70. data/lib/rollbar/truncation/remove_extra_strategy.rb +35 -0
  71. data/lib/rollbar/truncation/remove_request_strategy.rb +21 -0
  72. data/lib/rollbar/truncation/strings_strategy.rb +6 -5
  73. data/lib/rollbar/truncation.rb +9 -2
  74. data/lib/rollbar/util/hash.rb +15 -0
  75. data/lib/rollbar/util/ip_anonymizer.rb +8 -7
  76. data/lib/rollbar/util/ip_obfuscator.rb +1 -1
  77. data/lib/rollbar/util.rb +6 -2
  78. data/lib/rollbar/version.rb +1 -1
  79. data/lib/rollbar.rb +2 -3
  80. data/lib/tasks/benchmark.rake +103 -0
  81. data/rollbar.gemspec +13 -5
  82. data/spec/support/rollbar_api.rb +67 -0
  83. metadata +21 -23
  84. data/gemfiles/ruby_1_8_and_1_9_2.gemfile +0 -49
  85. data/lib/rollbar/json/default.rb +0 -11
  86. data/lib/rollbar/json/oj.rb +0 -16
@@ -1,5 +1,3 @@
1
- require 'capistrano'
2
- require 'capistrano/version'
3
1
  require 'rollbar/deploy'
4
2
 
5
3
  module Rollbar
@@ -10,15 +8,15 @@ module Rollbar
10
8
  deploy_task(logger, :desc => 'Notifying Rollbar of deployment start') do
11
9
  result = report_deploy_started(capistrano, dry_run)
12
10
 
13
- info_request_response(logger, result)
11
+ debug_request_response(logger, result)
14
12
 
15
13
  capistrano.set(:rollbar_deploy_id, 123) if dry_run
16
14
 
17
15
  skip_in_dry_run(logger, dry_run) do
18
- if (deploy_id = result[:data][:deploy_id])
16
+ if result[:success] && (deploy_id = result[:data] && result[:data][:deploy_id])
19
17
  capistrano.set :rollbar_deploy_id, deploy_id
20
18
  else
21
- logger.error 'Unable to report deploy to Rollbar'
19
+ logger.error 'Unable to report deploy to Rollbar' + (result[:message] ? ': ' + result[:message] : '')
22
20
  end
23
21
  end
24
22
  end
@@ -42,6 +40,9 @@ module Rollbar
42
40
  capistrano_300_warning(logger)
43
41
  logger.info opts[:desc] if opts[:desc]
44
42
  yield
43
+
44
+ rescue StandardError => e
45
+ logger.error "Error reporting to Rollbar: #{e.inspect}"
45
46
  end
46
47
 
47
48
  def deploy_update(capistrano, logger, dry_run, opts = {})
@@ -49,13 +50,13 @@ module Rollbar
49
50
  depend_on_deploy_id(capistrano, logger) do
50
51
  result = yield
51
52
 
52
- info_request_response(logger, result)
53
+ debug_request_response(logger, result)
53
54
 
54
55
  skip_in_dry_run(logger, dry_run) do
55
- if result[:response].is_a?(Net::HTTPSuccess)
56
+ if result[:success]
56
57
  logger.info 'Updated deploy status in Rollbar'
57
58
  else
58
- logger.error 'Unable to update deploy status in Rollbar'
59
+ logger.error 'Unable to update deploy status in Rollbar' + (result[:message] ? ': ' + result[:message] : '')
59
60
  end
60
61
  end
61
62
  end
@@ -63,7 +64,11 @@ module Rollbar
63
64
  end
64
65
 
65
66
  def capistrano_300_warning(logger)
66
- logger.warn("You need to upgrade capistrano to '>= 3.1' version in order to correctly report deploys to Rollbar. (On 3.0, the reported revision will be incorrect.)") if ::Capistrano::VERSION =~ /^3\.0/
67
+ return unless ::Capistrano.const_defined?('VERSION') && ::Capistrano::VERSION =~ /^3\.0/
68
+
69
+ logger.warn('You need to upgrade capistrano to >= 3.1 version in order'\
70
+ 'to correctly report deploys to Rollbar. (On 3.0, the reported revision'\
71
+ 'will be incorrect.)')
67
72
  end
68
73
 
69
74
  def report_deploy_started(capistrano, dry_run)
@@ -76,33 +81,35 @@ module Rollbar
76
81
  :proxy => :ENV,
77
82
  :dry_run => dry_run
78
83
  },
79
- :access_token => capistrano.fetch(:rollbar_token),
80
- :environment => capistrano.fetch(:rollbar_env),
81
- :revision => capistrano.fetch(:rollbar_revision)
84
+ capistrano.fetch(:rollbar_token),
85
+ capistrano.fetch(:rollbar_env),
86
+ capistrano.fetch(:rollbar_revision)
82
87
  )
83
88
  end
84
89
 
85
90
  def report_deploy_succeeded(capistrano, dry_run)
86
91
  ::Rollbar::Deploy.update(
87
92
  {
93
+ :comment => capistrano.fetch(:rollbar_comment),
88
94
  :proxy => :ENV,
89
95
  :dry_run => dry_run
90
96
  },
91
- :access_token => capistrano.fetch(:rollbar_token),
92
- :deploy_id => capistrano.fetch(:rollbar_deploy_id),
93
- :status => :succeeded
97
+ capistrano.fetch(:rollbar_token),
98
+ capistrano.fetch(:rollbar_deploy_id),
99
+ :succeeded
94
100
  )
95
101
  end
96
102
 
97
103
  def report_deploy_failed(capistrano, dry_run)
98
104
  ::Rollbar::Deploy.update(
99
105
  {
106
+ :comment => capistrano.fetch(:rollbar_comment),
100
107
  :proxy => :ENV,
101
108
  :dry_run => dry_run
102
109
  },
103
- :access_token => capistrano.fetch(:rollbar_token),
104
- :deploy_id => capistrano.fetch(:rollbar_deploy_id),
105
- :status => :failed
110
+ capistrano.fetch(:rollbar_token),
111
+ capistrano.fetch(:rollbar_deploy_id),
112
+ :failed
106
113
  )
107
114
  end
108
115
 
@@ -122,9 +129,10 @@ module Rollbar
122
129
  end
123
130
  end
124
131
 
125
- def info_request_response(logger, result)
126
- logger.info result[:request_info]
127
- logger.info result[:response_info] if result[:response_info]
132
+ def debug_request_response(logger, result)
133
+ # NOTE: in Capistrano debug messages go to log/capistrano.log but not to stdout even if log_level == :debug
134
+ logger.debug result[:request_info]
135
+ logger.debug result[:response_info] if result[:response_info]
128
136
  end
129
137
  end
130
138
  end
@@ -8,6 +8,7 @@ module Rollbar
8
8
  attr_accessor :async_handler
9
9
  attr_accessor :branch
10
10
  attr_reader :before_process
11
+ attr_accessor :capture_uncaught
11
12
  attr_accessor :code_version
12
13
  attr_accessor :custom_data_method
13
14
  attr_accessor :delayed_job_enabled
@@ -16,16 +17,18 @@ module Rollbar
16
17
  attr_accessor :disable_monkey_patch
17
18
  attr_accessor :disable_rack_monkey_patch
18
19
  attr_accessor :disable_core_monkey_patch
20
+ attr_accessor :enable_error_context
19
21
  attr_accessor :dj_threshold
22
+ attr_accessor :async_skip_report_handler
20
23
  attr_accessor :enabled
21
24
  attr_accessor :endpoint
22
25
  attr_accessor :environment
23
26
  attr_accessor :exception_level_filters
24
27
  attr_accessor :failover_handlers
25
- attr_accessor :filepath
26
28
  attr_accessor :framework
27
29
  attr_accessor :ignored_person_ids
28
30
  attr_accessor :host
31
+ attr_accessor :locals
29
32
  attr_writer :logger
30
33
  attr_accessor :payload_options
31
34
  attr_accessor :person_method
@@ -55,23 +58,36 @@ module Rollbar
55
58
  attr_reader :transform
56
59
  attr_accessor :verify_ssl_peer
57
60
  attr_accessor :use_async
61
+ attr_accessor :async_json_payload
58
62
  attr_reader :use_eventmachine
59
63
  attr_accessor :web_base
60
- attr_accessor :write_to_file
61
64
  attr_reader :send_extra_frame_data
62
65
  attr_accessor :use_exception_level_filters_default
63
66
  attr_accessor :proxy
67
+ attr_accessor :raise_on_error
68
+ attr_accessor :transmit
69
+ attr_accessor :log_payload
70
+ attr_accessor :backtrace_cleaner
71
+
72
+ attr_accessor :write_to_file
73
+ attr_accessor :filepath
74
+ attr_accessor :files_with_pid_name_enabled
75
+ attr_accessor :files_processed_enabled
76
+ attr_accessor :files_processed_duration # seconds
77
+ attr_accessor :files_processed_size # bytes
64
78
 
65
79
  attr_reader :project_gem_paths
80
+ attr_accessor :configured_options
66
81
 
67
- alias_method :safely?, :safely
82
+ alias safely? safely
68
83
 
69
- DEFAULT_ENDPOINT = 'https://api.rollbar.com/api/1/item/'
70
- DEFAULT_WEB_BASE = 'https://rollbar.com'
84
+ DEFAULT_ENDPOINT = 'https://api.rollbar.com/api/1/item/'.freeze
85
+ DEFAULT_WEB_BASE = 'https://rollbar.com'.freeze
71
86
 
72
87
  def initialize
73
88
  @async_handler = nil
74
89
  @before_process = []
90
+ @capture_uncaught = nil
75
91
  @code_version = nil
76
92
  @custom_data_method = nil
77
93
  @default_logger = lambda { ::Logger.new(STDERR) }
@@ -80,7 +96,9 @@ module Rollbar
80
96
  @disable_monkey_patch = false
81
97
  @disable_core_monkey_patch = false
82
98
  @disable_rack_monkey_patch = false
99
+ @enable_error_context = true
83
100
  @dj_threshold = 0
101
+ @async_skip_report_handler = nil
84
102
  @enabled = nil # set to true when configure is called
85
103
  @endpoint = DEFAULT_ENDPOINT
86
104
  @environment = nil
@@ -105,12 +123,13 @@ module Rollbar
105
123
  @net_retries = 3
106
124
  @js_enabled = false
107
125
  @js_options = {}
126
+ @locals = {}
108
127
  @scrub_fields = [:passwd, :password, :password_confirmation, :secret,
109
128
  :confirm_password, :password_confirmation, :secret_token,
110
- :api_key, :access_token, :session_id]
129
+ :api_key, :access_token, :accessToken, :session_id]
111
130
  @scrub_user = true
112
131
  @scrub_password = true
113
- @randomize_scrub_length = true
132
+ @randomize_scrub_length = false
114
133
  @scrub_whitelist = []
115
134
  @uncaught_exception_level = 'error'
116
135
  @scrub_headers = ['Authorization']
@@ -118,20 +137,32 @@ module Rollbar
118
137
  @safely = false
119
138
  @transform = []
120
139
  @use_async = false
140
+ @async_json_payload = false
121
141
  @use_eventmachine = false
122
142
  @verify_ssl_peer = true
123
143
  @web_base = DEFAULT_WEB_BASE
124
- @write_to_file = false
125
144
  @send_extra_frame_data = :none
126
145
  @project_gem_paths = []
127
146
  @use_exception_level_filters_default = false
128
147
  @proxy = nil
148
+ @raise_on_error = false
149
+ @transmit = true
150
+ @log_payload = false
129
151
  @collect_user_ip = true
130
152
  @anonymize_user_ip = false
153
+ @backtrace_cleaner = nil
131
154
  @hooks = {
132
155
  :on_error_response => nil, # params: response
133
- :on_report_internal_error => nil, # params: exception
156
+ :on_report_internal_error => nil # params: exception
134
157
  }
158
+
159
+ @write_to_file = false
160
+ @files_with_pid_name_enabled = false
161
+ @files_processed_enabled = false
162
+ @files_processed_duration = 60
163
+ @files_processed_size = 5 * 1000 * 1000
164
+
165
+ @configured_options = ConfiguredOptions.new(self)
135
166
  end
136
167
 
137
168
  def initialize_copy(orig)
@@ -139,9 +170,18 @@ module Rollbar
139
170
 
140
171
  instance_variables.each do |var|
141
172
  instance_var = instance_variable_get(var)
142
- instance_variable_set(var, Rollbar::Util::deep_copy(instance_var))
173
+ instance_variable_set(var, Rollbar::Util.deep_copy(instance_var))
174
+ end
175
+ end
176
+
177
+ def wrapped_clone
178
+ original_clone.tap do |new_config|
179
+ new_config.configured_options = ConfiguredOptions.new(new_config)
180
+ new_config.configured_options.configured = configured_options.configured
143
181
  end
144
182
  end
183
+ alias original_clone clone
184
+ alias clone wrapped_clone
145
185
 
146
186
  def merge(options)
147
187
  new_configuration = clone
@@ -210,9 +250,10 @@ module Rollbar
210
250
  value.is_a?(Hash) ? use_sidekiq(value) : use_sidekiq
211
251
  end
212
252
 
213
- def use_thread
253
+ def use_thread(options = {})
214
254
  require 'rollbar/delay/thread'
215
255
  @use_async = true
256
+ Rollbar::Delay::Thread.options = options
216
257
  @async_handler = Rollbar::Delay::Thread
217
258
  end
218
259
 
@@ -222,7 +263,7 @@ module Rollbar
222
263
  @async_handler = Rollbar::Delay::SuckerPunch
223
264
  end
224
265
 
225
- def use_sucker_punch=(value)
266
+ def use_sucker_punch=(_value)
226
267
  deprecation_message = '#use_sucker_punch=(value) has been deprecated in favor of #use_sucker_punch. Please update your rollbar configuration.'
227
268
  defined?(ActiveSupport) ? ActiveSupport::Deprecation.warn(deprecation_message) : puts(deprecation_message)
228
269
 
@@ -239,7 +280,10 @@ module Rollbar
239
280
  found = Gem::Specification.each.select { |spec| name === spec.name }
240
281
  puts "[Rollbar] No gems found matching #{name.inspect}" if found.empty?
241
282
  found
242
- end.flatten.uniq.map(&:gem_dir)
283
+ end
284
+ @project_gem_paths.flatten!
285
+ @project_gem_paths.uniq!
286
+ @project_gem_paths.map!(&:gem_dir)
243
287
  end
244
288
 
245
289
  def before_process=(*handler)
@@ -266,7 +310,11 @@ module Rollbar
266
310
  end
267
311
 
268
312
  def logger_level=(level)
269
- @logger_level = level.to_sym
313
+ @logger_level = if level
314
+ level.to_sym
315
+ else
316
+ level
317
+ end
270
318
  end
271
319
 
272
320
  def logger
@@ -274,14 +322,14 @@ module Rollbar
274
322
  end
275
323
 
276
324
  def hook(symbol, &block)
277
- if @hooks.has_key?(symbol)
325
+ if @hooks.key?(symbol)
278
326
  if block_given?
279
327
  @hooks[symbol] = block
280
328
  else
281
329
  @hooks[symbol]
282
330
  end
283
331
  else
284
- raise StandardError.new "Hook :" + symbol.to_s + " is not supported by Rollbar SDK."
332
+ raise StandardError, 'Hook :' + symbol.to_s + ' is not supported by Rollbar SDK.'
285
333
  end
286
334
  end
287
335
 
@@ -289,4 +337,26 @@ module Rollbar
289
337
  hook(symbol).call(*args) if hook(symbol).is_a?(Proc)
290
338
  end
291
339
  end
340
+
341
+ class ConfiguredOptions
342
+ attr_accessor :configuration, :configured
343
+
344
+ def initialize(configuration)
345
+ @configuration = configuration
346
+ @configured = {}
347
+ end
348
+
349
+ def method_missing(method, *args, &block)
350
+ return super unless configuration.respond_to?(method)
351
+
352
+ method_string = method.to_s
353
+ configured[method_string.chomp('=').to_sym] = args.first if method_string.end_with?('=')
354
+
355
+ configuration.send(method, *args, &block)
356
+ end
357
+
358
+ def respond_to_missing?(method)
359
+ configuration.respond_to?(method) || super
360
+ end
361
+ end
292
362
  end
@@ -11,14 +11,10 @@ module Rollbar
11
11
  end
12
12
 
13
13
  def queue
14
- @queue ||= self.queue_class.new(nil, :size => 5) do |payload|
15
- begin
16
- Rollbar.process_from_async_handler(payload)
17
- rescue
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
14
+ @queue ||= queue_class.new(nil, :size => 5) do |payload|
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
@@ -23,12 +23,9 @@ module Rollbar
23
23
  end
24
24
 
25
25
  def perform(payload)
26
- begin
27
- Rollbar.process_from_async_handler(payload)
28
- rescue
29
- # Raise the exception so Resque can track the errored job
30
- raise
31
- end
26
+ Rollbar.process_from_async_handler(payload)
27
+
28
+ # Do not rescue. Resque will call the error handler.
32
29
  end
33
30
  end
34
31
  end
@@ -10,21 +10,15 @@ module Rollbar
10
10
  end
11
11
 
12
12
  def call(payload)
13
- if ::Sidekiq::Client.push(@options.merge('args' => [payload])) == nil
14
- raise StandardError.new "Unable to push the job to Sidekiq"
15
- end
13
+ raise StandardError, 'Unable to push the job to Sidekiq' if ::Sidekiq::Client.push(@options.merge('args' => [payload])).nil?
16
14
  end
17
15
 
18
16
  include ::Sidekiq::Worker
19
17
 
20
18
  def perform(*args)
21
- begin
22
- Rollbar.process_from_async_handler(*args)
23
- rescue
24
- # Raise the exception so Sidekiq can track the errored job
25
- # and retry it
26
- raise
27
- end
19
+ Rollbar.process_from_async_handler(*args)
20
+
21
+ # Do not rescue. Sidekiq will call the error handler.
28
22
  end
29
23
  end
30
24
  end
@@ -16,11 +16,11 @@ module Rollbar
16
16
  def self.setup
17
17
  major_version = ::SuckerPunch::VERSION.split.first.to_i
18
18
 
19
- if major_version > 1
20
- self.perform_proc = proc { |payload| perform_async(payload) }
21
- else
22
- self.perform_proc = proc { |payload| new.async.perform(payload) }
23
- end
19
+ self.perform_proc = if major_version > 1
20
+ proc { |payload| perform_async(payload) }
21
+ else
22
+ proc { |payload| new.async.perform(payload) }
23
+ end
24
24
 
25
25
  self.ready = true
26
26
  end
@@ -32,20 +32,17 @@ module Rollbar
32
32
  end
33
33
 
34
34
  def perform(*args)
35
- begin
36
- Rollbar.process_from_async_handler(*args)
37
- rescue
38
- # SuckerPunch can configure an exception handler with:
39
- #
40
- # SuckerPunch.exception_handler { # do something here }
41
- #
42
- # This is just passed to Celluloid.exception_handler which will
43
- # push the reiceved block to an array of handlers, by default empty, [].
44
- #
45
- # We reraise the exception here casue it's safe and users could have defined
46
- # their own exception handler for SuckerPunch
47
- raise
48
- end
35
+ Rollbar.process_from_async_handler(*args)
36
+
37
+ # SuckerPunch can configure an exception handler with:
38
+ #
39
+ # SuckerPunch.exception_handler { # do something here }
40
+ #
41
+ # This is just passed to Celluloid.exception_handler which will
42
+ # push the reiceved block to an array of handlers, by default empty, [].
43
+ #
44
+
45
+ # Do not rescue. SuckerPunch will call the error handler.
49
46
  end
50
47
  end
51
48
  end
@@ -1,4 +1,3 @@
1
- require 'thread'
2
1
  require 'timeout'
3
2
 
4
3
  module Rollbar
@@ -10,7 +9,10 @@ module Rollbar
10
9
  Error = Class.new(StandardError)
11
10
  TimeoutError = Class.new(Error)
12
11
 
12
+ DEFAULT_PRIORITY = 1
13
+
13
14
  class << self
15
+ attr_writer :options
14
16
  attr_reader :reaper
15
17
 
16
18
  def call(payload)
@@ -21,6 +23,10 @@ module Rollbar
21
23
  thread
22
24
  end
23
25
 
26
+ def options
27
+ @options || {}
28
+ end
29
+
24
30
  private
25
31
 
26
32
  def threads
@@ -29,6 +35,7 @@ module Rollbar
29
35
 
30
36
  def spawn_threads_reaper
31
37
  return if @spawned
38
+
32
39
  @spawned = true
33
40
 
34
41
  @reaper ||= build_reaper_thread
@@ -61,11 +68,18 @@ 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
- rescue
82
+ rescue StandardError
69
83
  # Here we swallow the exception:
70
84
  # 1. The original report wasn't sent.
71
85
  # 2. An internal error was sent and logged
@@ -1,68 +1,91 @@
1
- require 'capistrano'
1
+ require 'json'
2
2
 
3
3
  module Rollbar
4
4
  # Deploy Tracking API wrapper module
5
5
  module Deploy
6
6
  ENDPOINT = 'https://api.rollbar.com/api/1/deploy/'.freeze
7
7
 
8
- def self.report(opts = {}, access_token:, environment:, revision:)
8
+ def self.report(opts, access_token, environment, revision)
9
+ return {} unless access_token && !access_token.empty?
10
+
9
11
  opts[:status] ||= :started
10
12
 
11
- uri = URI.parse(::Rollbar::Deploy::ENDPOINT)
13
+ uri = ::URI.parse(::Rollbar::Deploy::ENDPOINT)
12
14
 
13
- request = Net::HTTP::Post.new(uri.request_uri)
14
- request.body = ::JSON.dump({
15
+ request_data = {
15
16
  :access_token => access_token,
16
17
  :environment => environment,
17
18
  :revision => revision
18
- }.merge(opts))
19
+ }.merge(opts)
20
+ request_data.delete(:proxy)
21
+ request_data.delete(:dry_run)
22
+
23
+ request = ::Net::HTTP::Post.new(uri.request_uri)
24
+ request.body = ::JSON.dump(request_data)
19
25
 
20
- send_request(opts, :uri => uri, :request => request)
26
+ send_request(opts, uri, request)
21
27
  end
22
28
 
23
- def self.update(opts = {}, deploy_id:, access_token:, status:)
24
- uri = URI.parse(
29
+ def self.update(opts, access_token, deploy_id, status)
30
+ return {} unless access_token && !access_token.empty?
31
+
32
+ uri = ::URI.parse(
25
33
  ::Rollbar::Deploy::ENDPOINT +
26
34
  deploy_id.to_s +
27
35
  '?access_token=' + access_token
28
36
  )
29
37
 
30
- request = Net::HTTP::Patch.new(uri.request_uri)
38
+ request = ::Net::HTTP::Patch.new(uri.request_uri)
31
39
  request.body = ::JSON.dump(:status => status.to_s, :comment => opts[:comment])
32
40
 
33
- send_request(opts, :uri => uri, :request => request)
41
+ send_request(opts, uri, request)
34
42
  end
35
43
 
36
44
  class << self
37
45
  private
38
46
 
39
- def send_request(opts = {}, uri:, request:)
40
- Net::HTTP.start(uri.host, uri.port, opts[:proxy], :use_ssl => true) do |http|
47
+ def send_request(opts, uri, request)
48
+ ::Net::HTTP.start(uri.host, uri.port, opts[:proxy], :use_ssl => true) do |http|
41
49
  build_result(
42
- :uri => uri,
43
- :request => request,
44
- :response => opts[:dry_run] ? nil : http.request(request)
50
+ uri,
51
+ request,
52
+ opts[:dry_run] ? nil : http.request(request),
53
+ opts[:dry_run]
45
54
  )
46
55
  end
47
56
  end
48
57
 
49
- def build_result(uri:, request:, response: nil)
50
- result = {
51
- :request_info => uri.inspect + ': ' + request.body,
52
- :request => request,
53
- :response => response
54
- }
58
+ def build_result(uri, request, response = nil, dry_run = false)
59
+ result = {}
60
+ result.merge!(request_result(uri, request))
61
+ result.merge!(response_result(response)) unless response.nil?
62
+ result[:success] = success?(result, dry_run)
63
+ result
64
+ end
55
65
 
56
- unless result[:response].nil?
57
- result.merge!(JSON.parse(result[:response].body, :symbolize_names => true))
58
- result[:response_info] = build_response_info(result[:response])
59
- end
66
+ def success?(result, dry_run = false)
67
+ return true if dry_run
60
68
 
61
- result
69
+ result[:response] &&
70
+ result[:response].is_a?(::Net::HTTPSuccess) &&
71
+ result[:response].code == '200' &&
72
+ (result.key?('err') ? result['err'].to_i.zero? : true)
73
+ end
74
+
75
+ def request_result(uri, request)
76
+ {
77
+ :request_info => uri.inspect + ': ' + request.body,
78
+ :request => request
79
+ }
62
80
  end
63
81
 
64
- def build_response_info(response)
65
- response.code + '; ' + response.message + '; ' + response.body.delete!("\n")
82
+ def response_result(response)
83
+ {
84
+ :response => response,
85
+ :response_info => response.code + '; ' +
86
+ response.message + '; ' +
87
+ response.body.delete("\n")
88
+ }.merge(::JSON.parse(response.body, :symbolize_names => true))
66
89
  end
67
90
  end
68
91
  end