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