rollbar 2.23.2 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
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