rollbar 2.26.0 → 3.4.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.
- checksums.yaml +4 -4
- data/.github/pull_request_template.md +34 -0
- data/.github/workflows/ci.yml +104 -0
- data/.rubocop.yml +52 -36
- data/Gemfile +25 -29
- data/README.md +32 -8
- data/data/rollbar.snippet.js +1 -1
- data/docs/configuration.md +7 -0
- data/gemfiles/rails30.gemfile +17 -35
- data/gemfiles/rails31.gemfile +20 -37
- data/gemfiles/rails32.gemfile +13 -31
- data/gemfiles/rails40.gemfile +12 -32
- data/gemfiles/rails41.gemfile +11 -31
- data/gemfiles/rails42.gemfile +11 -35
- data/gemfiles/rails50.gemfile +14 -32
- data/gemfiles/rails51.gemfile +13 -31
- data/gemfiles/rails52.gemfile +10 -19
- data/gemfiles/rails60.gemfile +10 -25
- data/gemfiles/rails61.gemfile +52 -0
- data/gemfiles/rails70.gemfile +52 -0
- data/lib/generators/rollbar/rollbar_generator.rb +18 -14
- data/lib/rails/rollbar_runner.rb +8 -19
- data/lib/rollbar/capistrano.rb +17 -9
- data/lib/rollbar/capistrano3.rb +8 -2
- data/lib/rollbar/capistrano_tasks.rb +44 -8
- data/lib/rollbar/configuration.rb +122 -88
- data/lib/rollbar/delay/shoryuken.rb +4 -3
- data/lib/rollbar/delay/sidekiq.rb +3 -1
- data/lib/rollbar/delay/sucker_punch.rb +1 -2
- data/lib/rollbar/delay/thread.rb +3 -2
- data/lib/rollbar/deploy.rb +6 -7
- data/lib/rollbar/encoding/encoder.rb +7 -3
- data/lib/rollbar/encoding.rb +2 -7
- data/lib/rollbar/exception_reporter.rb +17 -8
- data/lib/rollbar/item/backtrace.rb +10 -8
- data/lib/rollbar/item/frame.rb +6 -5
- data/lib/rollbar/item/locals.rb +5 -2
- data/lib/rollbar/item.rb +60 -38
- data/lib/rollbar/json.rb +1 -1
- data/lib/rollbar/language_support.rb +0 -6
- data/lib/rollbar/lazy_store.rb +3 -7
- data/lib/rollbar/logger.rb +2 -0
- data/lib/rollbar/logger_proxy.rb +3 -1
- data/lib/rollbar/middleware/js/json_value.rb +15 -5
- data/lib/rollbar/middleware/js.rb +59 -37
- data/lib/rollbar/middleware/rack/builder.rb +3 -3
- data/lib/rollbar/middleware/rack/test_session.rb +3 -3
- data/lib/rollbar/middleware/rack.rb +4 -4
- data/lib/rollbar/middleware/rails/rollbar.rb +9 -6
- data/lib/rollbar/middleware/rails/show_exceptions.rb +8 -4
- data/lib/rollbar/notifier/trace_with_bindings.rb +13 -3
- data/lib/rollbar/notifier.rb +180 -136
- data/lib/rollbar/plugin.rb +8 -8
- data/lib/rollbar/plugins/active_job.rb +15 -2
- data/lib/rollbar/plugins/delayed_job/plugin.rb +14 -3
- data/lib/rollbar/plugins/goalie.rb +27 -16
- data/lib/rollbar/plugins/rails/controller_methods.rb +18 -14
- data/lib/rollbar/plugins/rails/railtie30.rb +2 -1
- data/lib/rollbar/plugins/rails/railtie32.rb +2 -1
- data/lib/rollbar/plugins/rails/railtie_mixin.rb +2 -2
- data/lib/rollbar/plugins/rails.rb +5 -2
- data/lib/rollbar/plugins/rake.rb +2 -1
- data/lib/rollbar/plugins/sidekiq/plugin.rb +39 -21
- data/lib/rollbar/plugins/sidekiq.rb +1 -1
- data/lib/rollbar/plugins/thread.rb +8 -7
- data/lib/rollbar/plugins/validations.rb +3 -1
- data/lib/rollbar/rake_tasks.rb +1 -2
- data/lib/rollbar/request_data_extractor.rb +48 -19
- data/lib/rollbar/rollbar_test.rb +9 -118
- data/lib/rollbar/scrubbers/params.rb +13 -7
- data/lib/rollbar/scrubbers/url.rb +56 -17
- data/lib/rollbar/scrubbers.rb +1 -1
- data/lib/rollbar/truncation/remove_any_key_strategy.rb +4 -1
- data/lib/rollbar/truncation/remove_extra_strategy.rb +3 -1
- data/lib/rollbar/util/hash.rb +14 -7
- data/lib/rollbar/util/ip_anonymizer.rb +1 -1
- data/lib/rollbar/util.rb +19 -13
- data/lib/rollbar/version.rb +1 -1
- data/lib/rollbar.rb +12 -7
- data/lib/tasks/benchmark.rake +2 -1
- data/rollbar.gemspec +5 -3
- metadata +17 -12
- data/.travis.yml +0 -284
- data/lib/rollbar/encoding/legacy_encoder.rb +0 -20
- /data/lib/generators/rollbar/templates/{initializer.rb → initializer.erb} +0 -0
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
|
-
|
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,9 +55,7 @@ module Rollbar
|
|
64
55
|
|
65
56
|
def build
|
66
57
|
data = build_data
|
67
|
-
self.payload = {
|
68
|
-
'data' => data
|
69
|
-
}
|
58
|
+
self.payload = add_access_token_to_payload({ 'data' => data })
|
70
59
|
|
71
60
|
enforce_valid_utf8
|
72
61
|
transform
|
@@ -74,7 +63,22 @@ module Rollbar
|
|
74
63
|
end
|
75
64
|
|
76
65
|
def build_data
|
77
|
-
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
|
+
{
|
78
82
|
:timestamp => Time.now.to_i,
|
79
83
|
:environment => build_environment,
|
80
84
|
:level => level,
|
@@ -88,25 +92,27 @@ module Rollbar
|
|
88
92
|
},
|
89
93
|
:body => build_body
|
90
94
|
}
|
91
|
-
|
92
|
-
data[:code_version] = configuration.code_version if configuration.code_version
|
93
|
-
data[:uuid] = SecureRandom.uuid if defined?(SecureRandom) && SecureRandom.respond_to?(:uuid)
|
95
|
+
end
|
94
96
|
|
95
|
-
|
96
|
-
|
97
|
+
def build_optional_data(data)
|
98
|
+
if configuration.project_gem_paths.any?
|
99
|
+
data[:project_package_paths] = configuration.project_gem_paths
|
100
|
+
end
|
97
101
|
|
98
|
-
|
99
|
-
# the key if value is nil.
|
100
|
-
data.delete(:context) unless data[:context]
|
102
|
+
data[:code_version] = configuration.code_version if configuration.code_version
|
101
103
|
|
102
|
-
|
104
|
+
return unless defined?(SecureRandom) && SecureRandom.respond_to?(:uuid)
|
105
|
+
|
106
|
+
data[:uuid] = SecureRandom.uuid
|
103
107
|
end
|
104
108
|
|
105
109
|
def configured_options
|
106
|
-
if Gem.loaded_specs['activesupport'] &&
|
107
|
-
|
108
|
-
#
|
109
|
-
#
|
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.
|
110
116
|
'not serialized in ActiveSupport < 4.1'
|
111
117
|
elsif configuration.use_async && !configuration.async_json_payload
|
112
118
|
# The setting allows serialization to be performed by each handler,
|
@@ -132,7 +138,7 @@ module Rollbar
|
|
132
138
|
nil
|
133
139
|
end
|
134
140
|
|
135
|
-
def handle_too_large_payload(stringified_payload,
|
141
|
+
def handle_too_large_payload(stringified_payload, _final_payload, attempts)
|
136
142
|
uuid = stringified_payload['data']['uuid']
|
137
143
|
host = stringified_payload['data'].fetch('server', {})['host']
|
138
144
|
|
@@ -144,17 +150,16 @@ module Rollbar
|
|
144
150
|
:host => host
|
145
151
|
}
|
146
152
|
|
147
|
-
notifier.send_failsafe(
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
)
|
152
|
-
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)}")
|
153
157
|
end
|
154
158
|
|
155
159
|
def too_large_payload_string(attempts)
|
156
160
|
'Could not send payload due to it being too large after truncating attempts. ' \
|
157
|
-
"Original size: #{attempts.first} Attempts: #{attempts.join(', ')}
|
161
|
+
"Original size: #{attempts.first} Attempts: #{attempts.join(', ')} " \
|
162
|
+
"Final size: #{attempts.last}"
|
158
163
|
end
|
159
164
|
|
160
165
|
def ignored?
|
@@ -166,6 +171,22 @@ module Rollbar
|
|
166
171
|
configuration.ignored_person_ids.include?(person_id)
|
167
172
|
end
|
168
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
|
+
|
169
190
|
private
|
170
191
|
|
171
192
|
def build_environment
|
@@ -194,7 +215,8 @@ module Rollbar
|
|
194
215
|
if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
|
195
216
|
Util.deep_merge(scrub(custom_data), merged_extra)
|
196
217
|
else
|
197
|
-
|
218
|
+
# avoid putting an empty {} in the payload.
|
219
|
+
merged_extra.empty? ? nil : merged_extra
|
198
220
|
end
|
199
221
|
end
|
200
222
|
|
data/lib/rollbar/json.rb
CHANGED
@@ -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
|
data/lib/rollbar/lazy_store.rb
CHANGED
@@ -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
|
80
|
-
|
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
|
data/lib/rollbar/logger.rb
CHANGED
@@ -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
|
data/lib/rollbar/logger_proxy.rb
CHANGED
@@ -23,7 +23,9 @@ module Rollbar
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def log(level, message)
|
26
|
-
|
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
|
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(
|
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(
|
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',
|
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(
|
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']
|
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(
|
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
|
-
|
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].
|
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
|
@@ -125,6 +134,7 @@ module Rollbar
|
|
125
134
|
|
126
135
|
def config_js_tag(env)
|
127
136
|
require 'json'
|
137
|
+
require 'rollbar/middleware/js/json_value'
|
128
138
|
|
129
139
|
js_config = Rollbar::Util.deep_copy(config[:options])
|
130
140
|
|
@@ -132,7 +142,7 @@ module Rollbar
|
|
132
142
|
|
133
143
|
# MUST use the Ruby JSON encoder (JSON#generate).
|
134
144
|
# See lib/rollbar/middleware/js/json_value
|
135
|
-
json = ::JSON.generate(js_config)
|
145
|
+
json = ::JSON.generate(js_config, Rollbar::JSON::JsOptionsState.new)
|
136
146
|
|
137
147
|
script_tag("var _rollbarConfig = #{json};", env)
|
138
148
|
end
|
@@ -155,14 +165,12 @@ module Rollbar
|
|
155
165
|
end
|
156
166
|
|
157
167
|
def script_tag(content, env)
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
script_tag_content = "\n<script type=\"text/javascript\">#{content}</script>"
|
165
|
-
end
|
168
|
+
nonce = rails5_nonce(env) || secure_headers_nonce(env)
|
169
|
+
script_tag_content = if nonce
|
170
|
+
"\n<script nonce=\"#{nonce}\">#{content}</script>"
|
171
|
+
else
|
172
|
+
"\n<script>#{content}</script>"
|
173
|
+
end
|
166
174
|
|
167
175
|
html_safe_if_needed(script_tag_content)
|
168
176
|
end
|
@@ -172,34 +180,46 @@ module Rollbar
|
|
172
180
|
string
|
173
181
|
end
|
174
182
|
|
175
|
-
# Rails 5.2 Secure Content Policy
|
183
|
+
# Rails 5.2+ Secure Content Policy
|
176
184
|
def rails5_nonce(env)
|
177
|
-
|
178
|
-
|
179
|
-
# Rails will
|
180
|
-
#
|
181
|
-
#
|
182
|
-
|
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.
|
183
195
|
req.respond_to?(:content_security_policy) &&
|
184
196
|
req.content_security_policy &&
|
185
197
|
req.content_security_policy.directives['script-src'] &&
|
186
|
-
!req.content_security_policy.directives['script-src'].include?("'unsafe-inline'") &&
|
187
198
|
req.content_security_policy_nonce
|
188
199
|
end
|
189
200
|
|
190
201
|
# Secure Headers gem
|
191
|
-
def secure_headers_nonce
|
192
|
-
|
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)
|
193
208
|
end
|
194
209
|
|
195
|
-
def secure_headers
|
210
|
+
def secure_headers(req)
|
196
211
|
return SecureHeadersFalse.new unless defined?(::SecureHeaders::Configuration)
|
197
212
|
|
198
|
-
|
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)
|
199
216
|
|
200
|
-
|
217
|
+
config = ::SecureHeaders::Configuration
|
201
218
|
|
202
|
-
|
219
|
+
has_nonce = ::SecureHeaders.respond_to?(
|
220
|
+
:content_security_policy_script_nonce
|
221
|
+
)
|
222
|
+
secure_headers_cls = if !has_nonce
|
203
223
|
SecureHeadersFalse
|
204
224
|
elsif config.respond_to?(:get)
|
205
225
|
SecureHeaders3To5
|
@@ -212,6 +232,11 @@ module Rollbar
|
|
212
232
|
secure_headers_cls.new
|
213
233
|
end
|
214
234
|
|
235
|
+
def secure_headers_nonce_key(req)
|
236
|
+
defined?(::SecureHeaders::NONCE_KEY) &&
|
237
|
+
req.env[::SecureHeaders::NONCE_KEY]
|
238
|
+
end
|
239
|
+
|
215
240
|
class SecureHeadersResolver
|
216
241
|
def append_nonce?
|
217
242
|
csp_needs_nonce?(find_csp)
|
@@ -224,16 +249,12 @@ module Rollbar
|
|
224
249
|
end
|
225
250
|
|
226
251
|
def csp_needs_nonce?(csp)
|
227
|
-
!opt_out?(csp)
|
252
|
+
!opt_out?(csp)
|
228
253
|
end
|
229
254
|
|
230
255
|
def opt_out?(_csp)
|
231
256
|
raise NotImplementedError
|
232
257
|
end
|
233
|
-
|
234
|
-
def unsafe_inline?(csp)
|
235
|
-
csp[:script_src].to_a.include?("'unsafe-inline'")
|
236
|
-
end
|
237
258
|
end
|
238
259
|
|
239
260
|
class SecureHeadersFalse < SecureHeadersResolver
|
@@ -253,7 +274,8 @@ module Rollbar
|
|
253
274
|
if csp.respond_to?(:opt_out?) && csp.opt_out?
|
254
275
|
csp.opt_out?
|
255
276
|
# secure_headers csp 3.0.x-3.4.x doesn't respond to 'opt_out?'
|
256
|
-
elsif defined?(::SecureHeaders::OPT_OUT) &&
|
277
|
+
elsif defined?(::SecureHeaders::OPT_OUT) &&
|
278
|
+
::SecureHeaders::OPT_OUT.is_a?(Symbol)
|
257
279
|
csp == ::SecureHeaders::OPT_OUT
|
258
280
|
end
|
259
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 =>
|
18
|
-
report_exception_to_rollbar(env,
|
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 =>
|
10
|
-
report_exception_to_rollbar(env,
|
11
|
-
raise
|
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(
|
48
|
-
|
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 =>
|
33
|
-
report_exception_to_rollbar(env,
|
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
|
-
|
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
|
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 =>
|
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,
|
28
|
+
report_exception_to_rollbar(env, e)
|
29
29
|
end
|
30
30
|
|
31
|
-
raise
|
31
|
+
raise e
|
32
32
|
end
|
33
33
|
|
34
34
|
def extract_scope_from(env)
|
35
35
|
scope = env['rollbar.scope']
|
36
|
-
|
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,
|
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
|
-
|
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
|
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
|