rollbar 2.23.2 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.github/pull_request_template.md +25 -0
  3. data/.github/workflows/ci.yml +118 -0
  4. data/.rubocop.yml +85 -34
  5. data/Gemfile +22 -22
  6. data/README.md +11 -9
  7. data/data/rollbar.snippet.js +1 -1
  8. data/docs/configuration.md +8 -0
  9. data/gemfiles/rails30.gemfile +18 -35
  10. data/gemfiles/rails31.gemfile +21 -37
  11. data/gemfiles/rails32.gemfile +14 -31
  12. data/gemfiles/rails40.gemfile +13 -32
  13. data/gemfiles/rails41.gemfile +12 -31
  14. data/gemfiles/rails42.gemfile +12 -35
  15. data/gemfiles/rails50.gemfile +17 -29
  16. data/gemfiles/rails51.gemfile +17 -29
  17. data/gemfiles/rails52.gemfile +7 -14
  18. data/gemfiles/rails60.gemfile +7 -20
  19. data/gemfiles/rails61.gemfile +54 -0
  20. data/lib/generators/rollbar/rollbar_generator.rb +18 -14
  21. data/lib/generators/rollbar/templates/{initializer.rb → initializer.erb} +0 -0
  22. data/lib/rails/rollbar_runner.rb +15 -6
  23. data/lib/rollbar/capistrano.rb +17 -9
  24. data/lib/rollbar/capistrano3.rb +8 -2
  25. data/lib/rollbar/capistrano_tasks.rb +44 -8
  26. data/lib/rollbar/configuration.rb +128 -84
  27. data/lib/rollbar/delay/shoryuken.rb +4 -3
  28. data/lib/rollbar/delay/sidekiq.rb +3 -1
  29. data/lib/rollbar/delay/sucker_punch.rb +1 -2
  30. data/lib/rollbar/delay/thread.rb +3 -2
  31. data/lib/rollbar/deploy.rb +8 -7
  32. data/lib/rollbar/encoding/encoder.rb +10 -3
  33. data/lib/rollbar/exception_reporter.rb +17 -8
  34. data/lib/rollbar/item/backtrace.rb +11 -9
  35. data/lib/rollbar/item/frame.rb +6 -5
  36. data/lib/rollbar/item/locals.rb +3 -2
  37. data/lib/rollbar/item.rb +68 -40
  38. data/lib/rollbar/json.rb +2 -1
  39. data/lib/rollbar/language_support.rb +0 -6
  40. data/lib/rollbar/lazy_store.rb +3 -7
  41. data/lib/rollbar/logger.rb +2 -0
  42. data/lib/rollbar/logger_proxy.rb +3 -1
  43. data/lib/rollbar/middleware/js.rb +64 -37
  44. data/lib/rollbar/middleware/rack/builder.rb +3 -3
  45. data/lib/rollbar/middleware/rack/test_session.rb +3 -3
  46. data/lib/rollbar/middleware/rack.rb +4 -4
  47. data/lib/rollbar/middleware/rails/rollbar.rb +9 -6
  48. data/lib/rollbar/middleware/rails/show_exceptions.rb +8 -4
  49. data/lib/rollbar/notifier/trace_with_bindings.rb +4 -2
  50. data/lib/rollbar/notifier.rb +272 -159
  51. data/lib/rollbar/plugin.rb +8 -8
  52. data/lib/rollbar/plugins/active_job.rb +11 -2
  53. data/lib/rollbar/plugins/delayed_job/plugin.rb +19 -2
  54. data/lib/rollbar/plugins/goalie.rb +27 -16
  55. data/lib/rollbar/plugins/rails/controller_methods.rb +18 -14
  56. data/lib/rollbar/plugins/rails/railtie30.rb +2 -1
  57. data/lib/rollbar/plugins/rails/railtie32.rb +2 -1
  58. data/lib/rollbar/plugins/rails/railtie_mixin.rb +2 -2
  59. data/lib/rollbar/plugins/rails.rb +5 -2
  60. data/lib/rollbar/plugins/rake.rb +2 -1
  61. data/lib/rollbar/plugins/sidekiq/plugin.rb +37 -20
  62. data/lib/rollbar/plugins/sidekiq.rb +1 -1
  63. data/lib/rollbar/plugins/thread.rb +8 -7
  64. data/lib/rollbar/plugins/validations.rb +3 -1
  65. data/lib/rollbar/rake_tasks.rb +1 -2
  66. data/lib/rollbar/request_data_extractor.rb +43 -16
  67. data/lib/rollbar/rollbar_test.rb +9 -118
  68. data/lib/rollbar/scrubbers/params.rb +13 -7
  69. data/lib/rollbar/scrubbers/url.rb +56 -17
  70. data/lib/rollbar/scrubbers.rb +1 -1
  71. data/lib/rollbar/truncation/remove_any_key_strategy.rb +4 -1
  72. data/lib/rollbar/truncation/remove_extra_strategy.rb +3 -1
  73. data/lib/rollbar/util/hash.rb +14 -7
  74. data/lib/rollbar/util/ip_anonymizer.rb +1 -1
  75. data/lib/rollbar/util.rb +19 -13
  76. data/lib/rollbar/version.rb +1 -1
  77. data/lib/rollbar.rb +12 -7
  78. data/lib/tasks/benchmark.rake +2 -1
  79. data/rollbar.gemspec +5 -2
  80. data/spec/support/rollbar_api.rb +67 -0
  81. metadata +9 -6
  82. data/.travis.yml +0 -284
data/lib/rollbar/item.rb CHANGED
@@ -23,24 +23,15 @@ module Rollbar
23
23
 
24
24
  attr_writer :payload
25
25
 
26
- attr_reader :level
27
- attr_reader :message
28
- attr_reader :exception
29
- attr_reader :extra
30
-
31
- attr_reader :configuration
32
- attr_reader :scope
33
- attr_reader :logger
34
- attr_reader :notifier
35
-
36
- attr_reader :context
26
+ attr_reader :level, :message, :exception, :extra, :configuration, :scope, :logger,
27
+ :notifier, :context
37
28
 
38
29
  def_delegators :payload, :[]
39
30
 
40
31
  class << self
41
32
  def build_with(payload, options = {})
42
33
  new(options).tap do |item|
43
- item.payload = payload
34
+ item.payload = item.add_access_token_to_payload(payload)
44
35
  end
45
36
  end
46
37
  end
@@ -64,10 +55,7 @@ module Rollbar
64
55
 
65
56
  def build
66
57
  data = build_data
67
- self.payload = {
68
- 'access_token' => configuration.access_token,
69
- 'data' => data
70
- }
58
+ self.payload = add_access_token_to_payload({ 'data' => data })
71
59
 
72
60
  enforce_valid_utf8
73
61
  transform
@@ -75,7 +63,22 @@ module Rollbar
75
63
  end
76
64
 
77
65
  def build_data
78
- data = {
66
+ data = initial_data
67
+
68
+ build_optional_data(data)
69
+
70
+ Util.deep_merge(data, configuration.payload_options)
71
+ Util.deep_merge(data, scope)
72
+
73
+ # Our API doesn't allow null context values, so just delete
74
+ # the key if value is nil.
75
+ data.delete(:context) unless data[:context]
76
+
77
+ data
78
+ end
79
+
80
+ def initial_data
81
+ {
79
82
  :timestamp => Time.now.to_i,
80
83
  :environment => build_environment,
81
84
  :level => level,
@@ -89,25 +92,27 @@ module Rollbar
89
92
  },
90
93
  :body => build_body
91
94
  }
92
- data[:project_package_paths] = configuration.project_gem_paths if configuration.project_gem_paths.any?
93
- data[:code_version] = configuration.code_version if configuration.code_version
94
- data[:uuid] = SecureRandom.uuid if defined?(SecureRandom) && SecureRandom.respond_to?(:uuid)
95
+ end
95
96
 
96
- Util.deep_merge(data, configuration.payload_options)
97
- Util.deep_merge(data, scope)
97
+ def build_optional_data(data)
98
+ if configuration.project_gem_paths.any?
99
+ data[:project_package_paths] = configuration.project_gem_paths
100
+ end
98
101
 
99
- # Our API doesn't allow null context values, so just delete
100
- # the key if value is nil.
101
- data.delete(:context) unless data[:context]
102
+ data[:code_version] = configuration.code_version if configuration.code_version
102
103
 
103
- data
104
+ return unless defined?(SecureRandom) && SecureRandom.respond_to?(:uuid)
105
+
106
+ data[:uuid] = SecureRandom.uuid
104
107
  end
105
108
 
106
109
  def configured_options
107
- if Gem.loaded_specs['activesupport'] && Gem.loaded_specs['activesupport'].version < Gem::Version.new('4.1')
108
- # There are too many types that crash ActiveSupport JSON serialization, and not worth
109
- # the risk just to send this diagnostic object. In versions < 4.1, ActiveSupport hooks
110
- # Ruby's JSON.generate so deeply there's no workaround.
110
+ if Gem.loaded_specs['activesupport'] &&
111
+ Gem.loaded_specs['activesupport'].version < Gem::Version.new('4.1')
112
+ # There are too many types that crash ActiveSupport JSON serialization,
113
+ # and not worth the risk just to send this diagnostic object.
114
+ # In versions < 4.1, ActiveSupport hooks Ruby's JSON.generate so deeply
115
+ # that there's no workaround.
111
116
  'not serialized in ActiveSupport < 4.1'
112
117
  elsif configuration.use_async && !configuration.async_json_payload
113
118
  # The setting allows serialization to be performed by each handler,
@@ -133,22 +138,28 @@ module Rollbar
133
138
  nil
134
139
  end
135
140
 
136
- def handle_too_large_payload(stringified_payload, final_payload, attempts)
141
+ def handle_too_large_payload(stringified_payload, _final_payload, attempts)
137
142
  uuid = stringified_payload['data']['uuid']
138
143
  host = stringified_payload['data'].fetch('server', {})['host']
139
144
 
140
- notifier.send_failsafe(
141
- too_large_payload_string(attempts),
142
- nil,
143
- uuid,
144
- host
145
- )
146
- logger.error("[Rollbar] Payload too large to be sent for UUID #{uuid}: #{Rollbar::JSON.dump(payload)}")
145
+ original_error = {
146
+ :message => message,
147
+ :exception => exception,
148
+ :configuration => configuration,
149
+ :uuid => uuid,
150
+ :host => host
151
+ }
152
+
153
+ notifier.send_failsafe(too_large_payload_string(attempts), nil, original_error)
154
+
155
+ logger.error('[Rollbar] Payload too large to be sent for UUID ' \
156
+ "#{uuid}: #{Rollbar::JSON.dump(payload)}")
147
157
  end
148
158
 
149
159
  def too_large_payload_string(attempts)
150
160
  'Could not send payload due to it being too large after truncating attempts. ' \
151
- "Original size: #{attempts.first} Attempts: #{attempts.join(', ')} Final size: #{attempts.last}"
161
+ "Original size: #{attempts.first} Attempts: #{attempts.join(', ')} " \
162
+ "Final size: #{attempts.last}"
152
163
  end
153
164
 
154
165
  def ignored?
@@ -160,6 +171,22 @@ module Rollbar
160
171
  configuration.ignored_person_ids.include?(person_id)
161
172
  end
162
173
 
174
+ def add_access_token_to_payload(payload)
175
+ # Some use cases remain where the token is needed in the payload. For example:
176
+ #
177
+ # When using async senders, if the access token is changed dynamically in
178
+ # the main process config, the sender process won't see that change.
179
+ #
180
+ # Until the delayed sender interface is changed to allow passing dynamic
181
+ # config options, this workaround allows the main process to set the token
182
+ # by adding it to the payload.
183
+ if configuration && configuration.use_payload_access_token
184
+ payload['access_token'] ||= configuration.access_token
185
+ end
186
+
187
+ payload
188
+ end
189
+
163
190
  private
164
191
 
165
192
  def build_environment
@@ -188,7 +215,8 @@ module Rollbar
188
215
  if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
189
216
  Util.deep_merge(scrub(custom_data), merged_extra)
190
217
  else
191
- merged_extra.empty? ? nil : merged_extra # avoid putting an empty {} in the payload.
218
+ # avoid putting an empty {} in the payload.
219
+ merged_extra.empty? ? nil : merged_extra
192
220
  end
193
221
  end
194
222
 
data/lib/rollbar/json.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  require 'rollbar/language_support'
2
+ require 'json'
2
3
 
3
4
  module Rollbar
4
5
  module JSON # :nodoc:
5
- extend self
6
+ module_function
6
7
 
7
8
  attr_writer :options_module
8
9
 
@@ -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
@@ -1,10 +1,8 @@
1
1
  module Rollbar
2
2
  class LazyStore
3
- attr_reader :loaded_data
3
+ attr_reader :loaded_data, :raw
4
4
  private :loaded_data
5
5
 
6
- attr_reader :raw
7
-
8
6
  def initialize(initial_data)
9
7
  initial_data ||= {}
10
8
 
@@ -41,8 +39,6 @@ module Rollbar
41
39
  raw[key] = value
42
40
 
43
41
  loaded_data.delete(key)
44
-
45
- value
46
42
  end
47
43
 
48
44
  def data
@@ -76,8 +72,8 @@ module Rollbar
76
72
  super
77
73
  end
78
74
 
79
- def respond_to?(method_sym)
80
- super || raw.respond_to?(method_sym)
75
+ def respond_to_missing?(method_sym, include_all)
76
+ raw.respond_to?(method_sym, include_all)
81
77
  end
82
78
  end
83
79
  end
@@ -16,7 +16,9 @@ module Rollbar
16
16
  # Rails.logger.extend(ActiveSupport::Logger.broadcast(Rollbar::Logger.new))
17
17
  class Logger < ::Logger
18
18
  class Error < RuntimeError; end
19
+
19
20
  class DatetimeFormatNotSupported < Error; end
21
+
20
22
  class FormatterNotSupported < Error; end
21
23
 
22
24
  def initialize
@@ -23,7 +23,9 @@ module Rollbar
23
23
  end
24
24
 
25
25
  def log(level, message)
26
- return unless Rollbar.configuration.enabled && acceptable_levels.include?(level.to_sym)
26
+ unless Rollbar.configuration.enabled && acceptable_levels.include?(level.to_sym)
27
+ return
28
+ end
27
29
 
28
30
  @object.send(level, message)
29
31
  rescue StandardError
@@ -10,11 +10,11 @@ module Rollbar
10
10
  class Js
11
11
  include Rollbar::RequestDataExtractor
12
12
 
13
- attr_reader :app
14
- attr_reader :config
13
+ attr_reader :app, :config
15
14
 
16
15
  JS_IS_INJECTED_KEY = 'rollbar.js_is_injected'.freeze
17
- SNIPPET = File.read(File.expand_path('../../../../data/rollbar.snippet.js', __FILE__))
16
+ SNIPPET = File.read(File.expand_path('../../../../data/rollbar.snippet.js',
17
+ __FILE__))
18
18
 
19
19
  def initialize(app, config)
20
20
  @app = app
@@ -30,7 +30,9 @@ module Rollbar
30
30
  response_string = add_js(env, app_result[2])
31
31
  build_response(env, app_result, response_string)
32
32
  rescue StandardError => e
33
- Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
33
+ Rollbar.log_error(
34
+ "[Rollbar] Rollbar.js could not be added because #{e} exception"
35
+ )
34
36
 
35
37
  app_result
36
38
  end
@@ -58,7 +60,8 @@ module Rollbar
58
60
  def streaming?(env)
59
61
  return false unless defined?(ActionController::Live)
60
62
 
61
- env['action_controller.instance'].class.included_modules.include?(ActionController::Live)
63
+ env['action_controller.instance']
64
+ .class.included_modules.include?(ActionController::Live)
62
65
  end
63
66
 
64
67
  def add_js(env, response)
@@ -72,7 +75,9 @@ module Rollbar
72
75
 
73
76
  build_body_with_js(env, body, insert_after_idx)
74
77
  rescue StandardError => e
75
- Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
78
+ Rollbar.log_error(
79
+ "[Rollbar] Rollbar.js could not be added because #{e} exception"
80
+ )
76
81
  nil
77
82
  end
78
83
 
@@ -80,12 +85,19 @@ module Rollbar
80
85
  return app_result unless response_string
81
86
 
82
87
  env[JS_IS_INJECTED_KEY] = true
83
- response = ::Rack::Response.new(response_string, app_result[0],
84
- app_result[1])
88
+
89
+ status, headers, = app_result
90
+ if headers.key?('Content-Length')
91
+ headers['Content-Length'] =
92
+ response_string.bytesize.to_s
93
+ end
94
+
95
+ response = ::Rack::Response.new(response_string, status, headers)
85
96
 
86
97
  finished = response.finish
87
98
 
88
- # Rack < 2.x Response#finish returns self in array[2]. Rack >= 2.x returns self.body.
99
+ # Rack < 2.x Response#finish returns self in array[2].
100
+ # Rack >= 2.x returns self.body.
89
101
  # Always return with the response object here regardless of rack version.
90
102
  finished[2] = response
91
103
  finished
@@ -121,6 +133,8 @@ module Rollbar
121
133
  end
122
134
 
123
135
  def config_js_tag(env)
136
+ require 'json'
137
+
124
138
  js_config = Rollbar::Util.deep_copy(config[:options])
125
139
 
126
140
  add_person_data(js_config, env)
@@ -150,14 +164,13 @@ module Rollbar
150
164
  end
151
165
 
152
166
  def script_tag(content, env)
153
- if (nonce = rails5_nonce(env))
154
- script_tag_content = "\n<script type=\"text/javascript\" nonce=\"#{nonce}\">#{content}</script>"
155
- elsif secure_headers_nonce?
156
- nonce = ::SecureHeaders.content_security_policy_script_nonce(::Rack::Request.new(env))
157
- script_tag_content = "\n<script type=\"text/javascript\" nonce=\"#{nonce}\">#{content}</script>"
158
- else
159
- script_tag_content = "\n<script type=\"text/javascript\">#{content}</script>"
160
- end
167
+ nonce = rails5_nonce(env) || secure_headers_nonce(env)
168
+ script_tag_content = if nonce
169
+ "\n<script type=\"text/javascript\" " \
170
+ "nonce=\"#{nonce}\">#{content}</script>"
171
+ else
172
+ "\n<script type=\"text/javascript\">#{content}</script>"
173
+ end
161
174
 
162
175
  html_safe_if_needed(script_tag_content)
163
176
  end
@@ -167,34 +180,46 @@ module Rollbar
167
180
  string
168
181
  end
169
182
 
170
- # Rails 5.2 Secure Content Policy
183
+ # Rails 5.2+ Secure Content Policy
171
184
  def rails5_nonce(env)
172
- # The nonce is the preferred method, however 'unsafe-inline' is also possible.
173
- # The app gets to decide, so we handle both. If the script_src key is missing,
174
- # Rails will not add the nonce to the headers, so we should not add it either.
175
- # If the 'unsafe-inline' value is present, the app should not add a nonce and
176
- # we should ignore it if they do.
177
- req = ::ActionDispatch::Request.new env
185
+ req = ::ActionDispatch::Request.new(env)
186
+
187
+ # Rails will only return a nonce if the app has set a nonce generator.
188
+ # So if we get a valid nonce here, we know we should use it.
189
+ #
190
+ # Having both 'unsafe-inline' and a nonce is a valid and preferred
191
+ # browser compatibility configuration.
192
+ #
193
+ # If the script_src key is missing, Rails will not add the nonce to the headers,
194
+ # so we detect this and will not add it in this case.
178
195
  req.respond_to?(:content_security_policy) &&
179
196
  req.content_security_policy &&
180
197
  req.content_security_policy.directives['script-src'] &&
181
- !req.content_security_policy.directives['script-src'].include?("'unsafe-inline'") &&
182
198
  req.content_security_policy_nonce
183
199
  end
184
200
 
185
201
  # Secure Headers gem
186
- def secure_headers_nonce?
187
- secure_headers.append_nonce?
202
+ def secure_headers_nonce(env)
203
+ req = ::Rack::Request.new(env)
204
+
205
+ return unless secure_headers(req).append_nonce?
206
+
207
+ ::SecureHeaders.content_security_policy_script_nonce(req)
188
208
  end
189
209
 
190
- def secure_headers
210
+ def secure_headers(req)
191
211
  return SecureHeadersFalse.new unless defined?(::SecureHeaders::Configuration)
192
212
 
193
- config = ::SecureHeaders::Configuration
213
+ # If the nonce key has been set, the app is using nonces for this request.
214
+ # If it hasn't, we shouldn't cause one to be added to script_src, so return now.
215
+ return SecureHeadersFalse.new unless secure_headers_nonce_key(req)
194
216
 
195
- secure_headers_cls = nil
217
+ config = ::SecureHeaders::Configuration
196
218
 
197
- secure_headers_cls = if !::SecureHeaders.respond_to?(:content_security_policy_script_nonce)
219
+ has_nonce = ::SecureHeaders.respond_to?(
220
+ :content_security_policy_script_nonce
221
+ )
222
+ secure_headers_cls = if !has_nonce
198
223
  SecureHeadersFalse
199
224
  elsif config.respond_to?(:get)
200
225
  SecureHeaders3To5
@@ -207,6 +232,11 @@ module Rollbar
207
232
  secure_headers_cls.new
208
233
  end
209
234
 
235
+ def secure_headers_nonce_key(req)
236
+ defined?(::SecureHeaders::NONCE_KEY) &&
237
+ req.env[::SecureHeaders::NONCE_KEY]
238
+ end
239
+
210
240
  class SecureHeadersResolver
211
241
  def append_nonce?
212
242
  csp_needs_nonce?(find_csp)
@@ -219,16 +249,12 @@ module Rollbar
219
249
  end
220
250
 
221
251
  def csp_needs_nonce?(csp)
222
- !opt_out?(csp) && !unsafe_inline?(csp)
252
+ !opt_out?(csp)
223
253
  end
224
254
 
225
255
  def opt_out?(_csp)
226
256
  raise NotImplementedError
227
257
  end
228
-
229
- def unsafe_inline?(csp)
230
- csp[:script_src].to_a.include?("'unsafe-inline'")
231
- end
232
258
  end
233
259
 
234
260
  class SecureHeadersFalse < SecureHeadersResolver
@@ -248,7 +274,8 @@ module Rollbar
248
274
  if csp.respond_to?(:opt_out?) && csp.opt_out?
249
275
  csp.opt_out?
250
276
  # secure_headers csp 3.0.x-3.4.x doesn't respond to 'opt_out?'
251
- elsif defined?(::SecureHeaders::OPT_OUT) && ::SecureHeaders::OPT_OUT.is_a?(Symbol)
277
+ elsif defined?(::SecureHeaders::OPT_OUT) &&
278
+ ::SecureHeaders::OPT_OUT.is_a?(Symbol)
252
279
  csp == ::SecureHeaders::OPT_OUT
253
280
  end
254
281
  end
@@ -14,8 +14,8 @@ module Rollbar
14
14
  Rollbar.scoped(fetch_scope(env)) do
15
15
  begin
16
16
  call_without_rollbar(env)
17
- rescue ::Exception => exception
18
- report_exception_to_rollbar(env, exception)
17
+ rescue ::Exception => e # rubocop:disable Lint/RescueException
18
+ report_exception_to_rollbar(env, e)
19
19
  raise
20
20
  end
21
21
  end
@@ -26,7 +26,7 @@ module Rollbar
26
26
  :request => proc { extract_request_data_from_rack(env) },
27
27
  :person => person_data_proc(env)
28
28
  }
29
- rescue Exception => e
29
+ rescue Exception => e # rubocop:disable Lint/RescueException
30
30
  report_exception_to_rollbar(env, e)
31
31
  raise
32
32
  end
@@ -6,9 +6,9 @@ module Rollbar
6
6
 
7
7
  def env_for_with_rollbar(path, env)
8
8
  env_for_without_rollbar(path, env)
9
- rescue Exception => exception
10
- report_exception_to_rollbar(env, exception)
11
- raise exception
9
+ rescue Exception => e # rubocop:disable Lint/RescueException
10
+ report_exception_to_rollbar(env, e)
11
+ raise e
12
12
  end
13
13
 
14
14
  def self.included(base)
@@ -21,7 +21,7 @@ module Rollbar
21
21
  response = @app.call(env)
22
22
  report_exception_to_rollbar(env, framework_error(env)) if framework_error(env)
23
23
  response
24
- rescue Exception => e
24
+ rescue Exception => e # rubocop:disable Lint/RescueException
25
25
  report_exception_to_rollbar(env, e)
26
26
  raise
27
27
  ensure
@@ -35,7 +35,7 @@ module Rollbar
35
35
  :request => proc { extract_request_data_from_rack(env) },
36
36
  :person => person_data_proc(env)
37
37
  }
38
- rescue Exception => e
38
+ rescue Exception => e # rubocop:disable Lint/RescueException
39
39
  report_exception_to_rollbar(env, e)
40
40
  raise
41
41
  end
@@ -44,8 +44,8 @@ module Rollbar
44
44
  proc { extract_person_data_from_controller(env) }
45
45
  end
46
46
 
47
- def framework_error(_env)
48
- nil
47
+ def framework_error(env)
48
+ env['rack.exception']
49
49
  end
50
50
  end
51
51
  end
@@ -29,8 +29,8 @@ module Rollbar
29
29
  end
30
30
 
31
31
  response
32
- rescue Exception => exception
33
- report_exception_to_rollbar(env, exception)
32
+ rescue Exception => e # rubocop:disable Lint/RescueException
33
+ report_exception_to_rollbar(env, e)
34
34
  raise
35
35
  ensure
36
36
  Rollbar.notifier.disable_locals
@@ -63,7 +63,9 @@ module Rollbar
63
63
 
64
64
  def person_data_proc(env)
65
65
  block = proc { extract_person_data_from_controller(env) }
66
- return block unless defined?(ActiveRecord::Base) && ActiveRecord::Base.connected?
66
+ unless defined?(ActiveRecord::Base) && ActiveRecord::Base.connected?
67
+ return block
68
+ end
67
69
 
68
70
  proc do
69
71
  begin
@@ -75,11 +77,12 @@ module Rollbar
75
77
  end
76
78
 
77
79
  def context(request_data)
78
- return unless request_data[:params]
79
-
80
80
  route_params = request_data[:params]
81
+
81
82
  # make sure route is a hash built by RequestDataExtractor
82
- return route_params[:controller].to_s + '#' + route_params[:action].to_s if route_params.is_a?(Hash) && !route_params.empty?
83
+ return unless route_params.is_a?(Hash) && !route_params.empty?
84
+
85
+ "#{route_params[:controller]}##{route_params[:action]}"
83
86
  end
84
87
  end
85
88
  end
@@ -20,20 +20,24 @@ module Rollbar
20
20
 
21
21
  def call_with_rollbar(env)
22
22
  call_without_rollbar(env)
23
- rescue ActionController::RoutingError => exception
23
+ rescue ActionController::RoutingError => e
24
24
  # won't reach here if show_detailed_exceptions is true
25
25
  scope = extract_scope_from(env)
26
26
 
27
27
  Rollbar.scoped(scope) do
28
- report_exception_to_rollbar(env, exception)
28
+ report_exception_to_rollbar(env, e)
29
29
  end
30
30
 
31
- raise exception
31
+ raise e
32
32
  end
33
33
 
34
34
  def extract_scope_from(env)
35
35
  scope = env['rollbar.scope']
36
- Rollbar.log_warn('[Rollbar] rollbar.scope key has been removed from Rack env.') unless scope
36
+ unless scope
37
+ Rollbar.log_warn(
38
+ '[Rollbar] rollbar.scope key has been removed from Rack env.'
39
+ )
40
+ end
37
41
 
38
42
  scope || {}
39
43
  end
@@ -36,7 +36,8 @@ module Rollbar
36
36
  def trace_point
37
37
  return unless defined?(TracePoint)
38
38
 
39
- @trace_point ||= TracePoint.new(:call, :return, :b_call, :b_return, :c_call, :c_return, :raise) do |tp|
39
+ @trace_point ||= TracePoint.new(:call, :return, :b_call, :b_return, :c_call,
40
+ :c_return, :raise) do |tp|
40
41
  case tp.event
41
42
  when :call, :b_call, :c_call, :class
42
43
  frames.push frame(tp)
@@ -44,7 +45,8 @@ module Rollbar
44
45
  frames.pop
45
46
  when :raise
46
47
  unless detect_reraise(tp) # ignore reraised exceptions
47
- @exception_frames = @frames.dup # may be possible to optimize better than #dup
48
+ # may be possible to optimize better than #dup
49
+ @exception_frames = @frames.dup
48
50
  @exception_signature = exception_signature(tp)
49
51
  end
50
52
  end