rollbar 3.1.2 → 3.3.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/.github/pull_request_template.md +15 -6
  3. data/.github/workflows/ci.yml +15 -29
  4. data/.rubocop.yml +84 -34
  5. data/Gemfile +13 -16
  6. data/README.md +1 -1
  7. data/data/rollbar.snippet.js +1 -1
  8. data/gemfiles/rails30.gemfile +10 -12
  9. data/gemfiles/rails31.gemfile +11 -13
  10. data/gemfiles/rails32.gemfile +4 -6
  11. data/gemfiles/rails40.gemfile +2 -5
  12. data/gemfiles/rails41.gemfile +2 -6
  13. data/gemfiles/rails42.gemfile +4 -10
  14. data/gemfiles/rails50.gemfile +8 -11
  15. data/gemfiles/rails51.gemfile +7 -10
  16. data/gemfiles/rails52.gemfile +8 -9
  17. data/gemfiles/rails60.gemfile +7 -9
  18. data/gemfiles/rails61.gemfile +7 -8
  19. data/gemfiles/rails70.gemfile +52 -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 +12 -5
  23. data/lib/rollbar/capistrano.rb +16 -8
  24. data/lib/rollbar/capistrano3.rb +8 -2
  25. data/lib/rollbar/capistrano_tasks.rb +37 -10
  26. data/lib/rollbar/configuration.rb +114 -90
  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 +6 -7
  32. data/lib/rollbar/encoding/encoder.rb +7 -3
  33. data/lib/rollbar/exception_reporter.rb +17 -8
  34. data/lib/rollbar/item/backtrace.rb +10 -8
  35. data/lib/rollbar/item/frame.rb +6 -5
  36. data/lib/rollbar/item/locals.rb +5 -1
  37. data/lib/rollbar/item.rb +47 -38
  38. data/lib/rollbar/json.rb +1 -1
  39. data/lib/rollbar/lazy_store.rb +1 -3
  40. data/lib/rollbar/logger.rb +2 -0
  41. data/lib/rollbar/logger_proxy.rb +3 -1
  42. data/lib/rollbar/middleware/js/json_value.rb +15 -5
  43. data/lib/rollbar/middleware/js.rb +57 -31
  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 +13 -3
  50. data/lib/rollbar/notifier.rb +179 -133
  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 +10 -3
  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 +39 -21
  62. data/lib/rollbar/plugins/sidekiq.rb +1 -1
  63. data/lib/rollbar/plugins/thread.rb +1 -1
  64. data/lib/rollbar/plugins/validations.rb +3 -1
  65. data/lib/rollbar/rake_tasks.rb +0 -1
  66. data/lib/rollbar/request_data_extractor.rb +38 -17
  67. data/lib/rollbar/rollbar_test.rb +3 -1
  68. data/lib/rollbar/scrubbers/params.rb +13 -7
  69. data/lib/rollbar/scrubbers/url.rb +37 -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 +3 -1
  80. metadata +5 -4
data/lib/rollbar/item.rb CHANGED
@@ -23,17 +23,8 @@ 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
 
@@ -64,7 +55,7 @@ module Rollbar
64
55
 
65
56
  def build
66
57
  data = build_data
67
- self.payload = add_access_token_to_payload({'data' => data})
58
+ self.payload = add_access_token_to_payload({ 'data' => data })
68
59
 
69
60
  enforce_valid_utf8
70
61
  transform
@@ -72,7 +63,22 @@ module Rollbar
72
63
  end
73
64
 
74
65
  def build_data
75
- 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
+ {
76
82
  :timestamp => Time.now.to_i,
77
83
  :environment => build_environment,
78
84
  :level => level,
@@ -86,25 +92,27 @@ module Rollbar
86
92
  },
87
93
  :body => build_body
88
94
  }
89
- data[:project_package_paths] = configuration.project_gem_paths if configuration.project_gem_paths.any?
90
- data[:code_version] = configuration.code_version if configuration.code_version
91
- data[:uuid] = SecureRandom.uuid if defined?(SecureRandom) && SecureRandom.respond_to?(:uuid)
95
+ end
92
96
 
93
- Util.deep_merge(data, configuration.payload_options)
94
- 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
95
101
 
96
- # Our API doesn't allow null context values, so just delete
97
- # the key if value is nil.
98
- data.delete(:context) unless data[:context]
102
+ data[:code_version] = configuration.code_version if configuration.code_version
99
103
 
100
- data
104
+ return unless defined?(SecureRandom) && SecureRandom.respond_to?(:uuid)
105
+
106
+ data[:uuid] = SecureRandom.uuid
101
107
  end
102
108
 
103
109
  def configured_options
104
- if Gem.loaded_specs['activesupport'] && Gem.loaded_specs['activesupport'].version < Gem::Version.new('4.1')
105
- # There are too many types that crash ActiveSupport JSON serialization, and not worth
106
- # the risk just to send this diagnostic object. In versions < 4.1, ActiveSupport hooks
107
- # 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.
108
116
  'not serialized in ActiveSupport < 4.1'
109
117
  elsif configuration.use_async && !configuration.async_json_payload
110
118
  # The setting allows serialization to be performed by each handler,
@@ -130,7 +138,7 @@ module Rollbar
130
138
  nil
131
139
  end
132
140
 
133
- def handle_too_large_payload(stringified_payload, final_payload, attempts)
141
+ def handle_too_large_payload(stringified_payload, _final_payload, attempts)
134
142
  uuid = stringified_payload['data']['uuid']
135
143
  host = stringified_payload['data'].fetch('server', {})['host']
136
144
 
@@ -142,17 +150,16 @@ module Rollbar
142
150
  :host => host
143
151
  }
144
152
 
145
- notifier.send_failsafe(
146
- too_large_payload_string(attempts),
147
- nil,
148
- original_error
149
- )
150
- logger.error("[Rollbar] Payload too large to be sent for UUID #{uuid}: #{Rollbar::JSON.dump(payload)}")
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)}")
151
157
  end
152
158
 
153
159
  def too_large_payload_string(attempts)
154
160
  'Could not send payload due to it being too large after truncating attempts. ' \
155
- "Original size: #{attempts.first} Attempts: #{attempts.join(', ')} Final size: #{attempts.last}"
161
+ "Original size: #{attempts.first} Attempts: #{attempts.join(', ')} " \
162
+ "Final size: #{attempts.last}"
156
163
  end
157
164
 
158
165
  def ignored?
@@ -170,9 +177,10 @@ module Rollbar
170
177
  # When using async senders, if the access token is changed dynamically in
171
178
  # the main process config, the sender process won't see that change.
172
179
  #
173
- # Until the delayed sender interface is changed to allow passing dynamic config options,
174
- # this workaround allows the main process to set the token by adding it to the payload.
175
- if (configuration && configuration.use_payload_access_token)
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
176
184
  payload['access_token'] ||= configuration.access_token
177
185
  end
178
186
 
@@ -207,7 +215,8 @@ module Rollbar
207
215
  if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
208
216
  Util.deep_merge(scrub(custom_data), merged_extra)
209
217
  else
210
- 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
211
220
  end
212
221
  end
213
222
 
data/lib/rollbar/json.rb CHANGED
@@ -3,7 +3,7 @@ require 'json'
3
3
 
4
4
  module Rollbar
5
5
  module JSON # :nodoc:
6
- extend self
6
+ module_function
7
7
 
8
8
  attr_writer :options_module
9
9
 
@@ -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
 
@@ -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
@@ -1,8 +1,12 @@
1
- # Allows a Ruby String to be used to create native Javascript objects
2
- # when calling JSON#generate.
1
+ # Allows a Ruby String to be used to pass native Javascript objects/functions
2
+ # when calling JSON#generate with a Rollbar::JSON::JsOptionsState instance.
3
3
  #
4
4
  # Example:
5
- # JSON.generate({ foo: Rollbar::JSON::Value.new('function(){ alert("bar") }') })
5
+ # JSON.generate(
6
+ # { foo: Rollbar::JSON::Value.new('function(){ alert("bar") }') },
7
+ # Rollbar::JSON::JsOptionsState.new
8
+ # )
9
+ #
6
10
  # => '{"foo":function(){ alert(\"bar\") }}'
7
11
  #
8
12
  # MUST use the Ruby JSON encoder, as in the example. The ActiveSupport encoder,
@@ -11,6 +15,8 @@
11
15
  #
12
16
  module Rollbar
13
17
  module JSON
18
+ class JsOptionsState < ::JSON::State; end
19
+
14
20
  class Value # :nodoc:
15
21
  attr_accessor :value
16
22
 
@@ -18,8 +24,12 @@ module Rollbar
18
24
  @value = value
19
25
  end
20
26
 
21
- def to_json(*_args)
22
- value
27
+ def to_json(opts = {})
28
+ # Return the raw value if this is from the js middleware
29
+ return value if opts.class == Rollbar::JSON::JsOptionsState
30
+
31
+ # Otherwise convert to a string
32
+ %Q["#{value}"]
23
33
  end
24
34
  end
25
35
  end
@@ -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
 
@@ -82,13 +87,17 @@ module Rollbar
82
87
  env[JS_IS_INJECTED_KEY] = true
83
88
 
84
89
  status, headers, = app_result
85
- headers['Content-Length'] = response_string.bytesize.to_s if headers.key?('Content-Length')
90
+ if headers.key?('Content-Length')
91
+ headers['Content-Length'] =
92
+ response_string.bytesize.to_s
93
+ end
86
94
 
87
95
  response = ::Rack::Response.new(response_string, status, headers)
88
96
 
89
97
  finished = response.finish
90
98
 
91
- # 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.
92
101
  # Always return with the response object here regardless of rack version.
93
102
  finished[2] = response
94
103
  finished
@@ -132,7 +141,7 @@ module Rollbar
132
141
 
133
142
  # MUST use the Ruby JSON encoder (JSON#generate).
134
143
  # See lib/rollbar/middleware/js/json_value
135
- json = ::JSON.generate(js_config)
144
+ json = ::JSON.generate(js_config, Rollbar::JSON::JsOptionsState.new)
136
145
 
137
146
  script_tag("var _rollbarConfig = #{json};", env)
138
147
  end
@@ -155,14 +164,12 @@ module Rollbar
155
164
  end
156
165
 
157
166
  def script_tag(content, env)
158
- if (nonce = rails5_nonce(env))
159
- script_tag_content = "\n<script type=\"text/javascript\" nonce=\"#{nonce}\">#{content}</script>"
160
- elsif secure_headers_nonce?
161
- nonce = ::SecureHeaders.content_security_policy_script_nonce(::Rack::Request.new(env))
162
- script_tag_content = "\n<script type=\"text/javascript\" nonce=\"#{nonce}\">#{content}</script>"
163
- else
164
- script_tag_content = "\n<script type=\"text/javascript\">#{content}</script>"
165
- end
167
+ nonce = rails5_nonce(env) || secure_headers_nonce(env)
168
+ script_tag_content = if nonce
169
+ "\n<script nonce=\"#{nonce}\">#{content}</script>"
170
+ else
171
+ "\n<script>#{content}</script>"
172
+ end
166
173
 
167
174
  html_safe_if_needed(script_tag_content)
168
175
  end
@@ -172,14 +179,18 @@ module Rollbar
172
179
  string
173
180
  end
174
181
 
175
- # Rails 5.2 Secure Content Policy
182
+ # Rails 5.2+ Secure Content Policy
176
183
  def rails5_nonce(env)
177
- # The nonce is the preferred method, however 'unsafe-inline' is also possible.
178
- # The app gets to decide, so we handle both. If the script_src key is missing,
179
- # Rails will not add the nonce to the headers, so we should not add it either.
180
- # If the 'unsafe-inline' value is present, the app should not add a nonce and
181
- # we should ignore it if they do.
182
- req = ::ActionDispatch::Request.new env
184
+ req = ::ActionDispatch::Request.new(env)
185
+
186
+ # Rails will only return a nonce if the app has set a nonce generator.
187
+ # So if we get a valid nonce here, we know we should use it.
188
+ #
189
+ # Having both 'unsafe-inline' and a nonce is a valid and preferred
190
+ # browser compatibility configuration.
191
+ #
192
+ # If the script_src key is missing, Rails will not add the nonce to the headers,
193
+ # so we detect this and will not add it in this case.
183
194
  req.respond_to?(:content_security_policy) &&
184
195
  req.content_security_policy &&
185
196
  req.content_security_policy.directives['script-src'] &&
@@ -187,18 +198,27 @@ module Rollbar
187
198
  end
188
199
 
189
200
  # Secure Headers gem
190
- def secure_headers_nonce?
191
- secure_headers.append_nonce?
201
+ def secure_headers_nonce(env)
202
+ req = ::Rack::Request.new(env)
203
+
204
+ return unless secure_headers(req).append_nonce?
205
+
206
+ ::SecureHeaders.content_security_policy_script_nonce(req)
192
207
  end
193
208
 
194
- def secure_headers
209
+ def secure_headers(req)
195
210
  return SecureHeadersFalse.new unless defined?(::SecureHeaders::Configuration)
196
211
 
197
- config = ::SecureHeaders::Configuration
212
+ # If the nonce key has been set, the app is using nonces for this request.
213
+ # If it hasn't, we shouldn't cause one to be added to script_src, so return now.
214
+ return SecureHeadersFalse.new unless secure_headers_nonce_key(req)
198
215
 
199
- secure_headers_cls = nil
216
+ config = ::SecureHeaders::Configuration
200
217
 
201
- secure_headers_cls = if !::SecureHeaders.respond_to?(:content_security_policy_script_nonce)
218
+ has_nonce = ::SecureHeaders.respond_to?(
219
+ :content_security_policy_script_nonce
220
+ )
221
+ secure_headers_cls = if !has_nonce
202
222
  SecureHeadersFalse
203
223
  elsif config.respond_to?(:get)
204
224
  SecureHeaders3To5
@@ -211,6 +231,11 @@ module Rollbar
211
231
  secure_headers_cls.new
212
232
  end
213
233
 
234
+ def secure_headers_nonce_key(req)
235
+ defined?(::SecureHeaders::NONCE_KEY) &&
236
+ req.env[::SecureHeaders::NONCE_KEY]
237
+ end
238
+
214
239
  class SecureHeadersResolver
215
240
  def append_nonce?
216
241
  csp_needs_nonce?(find_csp)
@@ -248,7 +273,8 @@ module Rollbar
248
273
  if csp.respond_to?(:opt_out?) && csp.opt_out?
249
274
  csp.opt_out?
250
275
  # 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)
276
+ elsif defined?(::SecureHeaders::OPT_OUT) &&
277
+ ::SecureHeaders::OPT_OUT.is_a?(Symbol)
252
278
  csp == ::SecureHeaders::OPT_OUT
253
279
  end
254
280
  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
@@ -53,13 +55,21 @@ module Rollbar
53
55
 
54
56
  def frame(trace)
55
57
  {
56
- :binding => trace.binding,
58
+ :binding => binding(trace),
57
59
  :defined_class => trace.defined_class,
58
60
  :method_id => trace.method_id,
59
61
  :path => trace.path,
60
62
  :lineno => trace.lineno
61
63
  }
62
64
  end
65
+
66
+ def binding(trace)
67
+ trace.binding
68
+ rescue StandardError
69
+ # Ruby internals will raise if we're on a Fiber,
70
+ # since bindings aren't valid on Fibers.
71
+ nil
72
+ end
63
73
  end
64
74
  end
65
75
  end