rollbar 2.22.1 → 2.27.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.
- checksums.yaml +4 -4
- data/.github/pull_request_template.md +25 -0
- data/.rubocop.yml +136 -0
- data/.travis.yml +33 -30
- data/Gemfile +2 -0
- data/README.md +1 -1
- data/data/rollbar.snippet.js +1 -1
- data/docs/configuration.md +8 -0
- data/gemfiles/rails42.gemfile +4 -0
- data/gemfiles/rails50.gemfile +6 -2
- data/gemfiles/rails51.gemfile +6 -2
- data/gemfiles/rails60.gemfile +1 -1
- data/lib/rails/rollbar_runner.rb +3 -1
- data/lib/rollbar/capistrano.rb +1 -1
- data/lib/rollbar/capistrano_tasks.rb +10 -1
- data/lib/rollbar/configuration.rb +28 -6
- data/lib/rollbar/delay/girl_friday.rb +3 -7
- data/lib/rollbar/delay/resque.rb +2 -3
- data/lib/rollbar/delay/sidekiq.rb +2 -4
- data/lib/rollbar/delay/sucker_punch.rb +3 -4
- data/lib/rollbar/delay/thread.rb +14 -0
- data/lib/rollbar/deploy.rb +2 -0
- data/lib/rollbar/encoding/encoder.rb +10 -3
- data/lib/rollbar/item/backtrace.rb +12 -2
- data/lib/rollbar/item/frame.rb +2 -0
- data/lib/rollbar/item/locals.rb +45 -1
- data/lib/rollbar/item.rb +22 -14
- data/lib/rollbar/json.rb +1 -0
- data/lib/rollbar/middleware/js.rb +13 -3
- data/lib/rollbar/notifier.rb +154 -61
- data/lib/rollbar/plugins/active_job.rb +6 -2
- data/lib/rollbar/plugins/delayed_job/plugin.rb +11 -1
- data/lib/rollbar/plugins/error_context.rb +11 -0
- data/lib/rollbar/rake_tasks.rb +1 -1
- data/lib/rollbar/request_data_extractor.rb +7 -1
- data/lib/rollbar/rollbar_test.rb +6 -117
- data/lib/rollbar/scrubbers/url.rb +10 -5
- data/lib/rollbar/scrubbers.rb +1 -5
- data/lib/rollbar/truncation/frames_strategy.rb +1 -1
- data/lib/rollbar/truncation/mixin.rb +1 -1
- data/lib/rollbar/truncation/strings_strategy.rb +4 -2
- data/lib/rollbar/util.rb +4 -0
- data/lib/rollbar/version.rb +1 -1
- data/rollbar.gemspec +1 -0
- data/spec/support/rollbar_api.rb +67 -0
- metadata +6 -4
@@ -17,10 +17,8 @@ module Rollbar
|
|
17
17
|
|
18
18
|
def perform(*args)
|
19
19
|
Rollbar.process_from_async_handler(*args)
|
20
|
-
|
21
|
-
#
|
22
|
-
# and retry it
|
23
|
-
raise
|
20
|
+
|
21
|
+
# Do not rescue. Sidekiq will call the error handler.
|
24
22
|
end
|
25
23
|
end
|
26
24
|
end
|
@@ -33,7 +33,7 @@ module Rollbar
|
|
33
33
|
|
34
34
|
def perform(*args)
|
35
35
|
Rollbar.process_from_async_handler(*args)
|
36
|
-
|
36
|
+
|
37
37
|
# SuckerPunch can configure an exception handler with:
|
38
38
|
#
|
39
39
|
# SuckerPunch.exception_handler { # do something here }
|
@@ -41,9 +41,8 @@ module Rollbar
|
|
41
41
|
# This is just passed to Celluloid.exception_handler which will
|
42
42
|
# push the reiceved block to an array of handlers, by default empty, [].
|
43
43
|
#
|
44
|
-
|
45
|
-
#
|
46
|
-
raise
|
44
|
+
|
45
|
+
# Do not rescue. SuckerPunch will call the error handler.
|
47
46
|
end
|
48
47
|
end
|
49
48
|
end
|
data/lib/rollbar/delay/thread.rb
CHANGED
@@ -9,7 +9,10 @@ module Rollbar
|
|
9
9
|
Error = Class.new(StandardError)
|
10
10
|
TimeoutError = Class.new(Error)
|
11
11
|
|
12
|
+
DEFAULT_PRIORITY = 1
|
13
|
+
|
12
14
|
class << self
|
15
|
+
attr_writer :options
|
13
16
|
attr_reader :reaper
|
14
17
|
|
15
18
|
def call(payload)
|
@@ -20,6 +23,10 @@ module Rollbar
|
|
20
23
|
thread
|
21
24
|
end
|
22
25
|
|
26
|
+
def options
|
27
|
+
@options || {}
|
28
|
+
end
|
29
|
+
|
23
30
|
private
|
24
31
|
|
25
32
|
def threads
|
@@ -61,9 +68,16 @@ module Rollbar
|
|
61
68
|
end
|
62
69
|
end # class << self
|
63
70
|
|
71
|
+
def priority
|
72
|
+
self.class.options[:priority] || DEFAULT_PRIORITY
|
73
|
+
end
|
74
|
+
|
64
75
|
def call(payload)
|
76
|
+
priority = self.priority
|
77
|
+
|
65
78
|
::Thread.new do
|
66
79
|
begin
|
80
|
+
::Thread.current.priority = priority
|
67
81
|
Rollbar.process_from_async_handler(payload)
|
68
82
|
rescue StandardError
|
69
83
|
# Here we swallow the exception:
|
data/lib/rollbar/deploy.rb
CHANGED
@@ -3,7 +3,6 @@ module Rollbar
|
|
3
3
|
class Encoder
|
4
4
|
ALL_ENCODINGS = [::Encoding::UTF_8, ::Encoding::ISO_8859_1, ::Encoding::ASCII_8BIT, ::Encoding::US_ASCII].freeze
|
5
5
|
ASCII_ENCODINGS = [::Encoding::US_ASCII, ::Encoding::ASCII_8BIT, ::Encoding::ISO_8859_1].freeze
|
6
|
-
ENCODING_OPTIONS = { :invalid => :replace, :undef => :replace, :replace => '' }.freeze
|
7
6
|
UTF8 = 'UTF-8'.freeze
|
8
7
|
BINARY = 'binary'.freeze
|
9
8
|
|
@@ -21,10 +20,19 @@ module Rollbar
|
|
21
20
|
encoded_value = if encoding == ::Encoding::UTF_8 && value.valid_encoding?
|
22
21
|
value
|
23
22
|
else
|
24
|
-
force_encoding(value).encode(
|
23
|
+
force_encoding(value).encode(
|
24
|
+
*encoding_args(value),
|
25
|
+
# Ruby 2.7 requires this to look like keyword args,
|
26
|
+
# and Ruby 1.9.3 doesn't understand keyword args, so
|
27
|
+
# don't use hash rockets here and both will be happy.
|
28
|
+
invalid: :replace, undef: :replace, replace: '' # rubocop:disable Style/HashSyntax
|
29
|
+
)
|
25
30
|
end
|
26
31
|
|
27
32
|
object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value
|
33
|
+
rescue StandardError => e
|
34
|
+
# If encoding fails for any reason, replace the string with a diagnostic error.
|
35
|
+
"error encoding string: #{e.class}: #{e.message}"
|
28
36
|
end
|
29
37
|
|
30
38
|
private
|
@@ -54,7 +62,6 @@ module Rollbar
|
|
54
62
|
def encoding_args(value)
|
55
63
|
args = [UTF8]
|
56
64
|
args << BINARY if ASCII_ENCODINGS.include?(value.encoding)
|
57
|
-
args << ENCODING_OPTIONS
|
58
65
|
|
59
66
|
args
|
60
67
|
end
|
@@ -74,10 +74,20 @@ module Rollbar
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def map_frames(current_exception)
|
77
|
-
|
77
|
+
frames = cleaned_backtrace(current_exception).map do |frame|
|
78
78
|
Rollbar::Item::Frame.new(self, frame,
|
79
79
|
:configuration => configuration).to_h
|
80
|
-
end
|
80
|
+
end
|
81
|
+
frames.reverse!
|
82
|
+
end
|
83
|
+
|
84
|
+
def cleaned_backtrace(current_exception)
|
85
|
+
normalized_backtrace = exception_backtrace(current_exception)
|
86
|
+
if configuration.backtrace_cleaner
|
87
|
+
configuration.backtrace_cleaner.clean(normalized_backtrace)
|
88
|
+
else
|
89
|
+
normalized_backtrace
|
90
|
+
end
|
81
91
|
end
|
82
92
|
|
83
93
|
# Returns the backtrace to be sent to our API. There are 3 options:
|
data/lib/rollbar/item/frame.rb
CHANGED
data/lib/rollbar/item/locals.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rollbar/notifier'
|
2
2
|
require 'rollbar/scrubbers/params'
|
3
|
+
require 'rollbar/util'
|
3
4
|
|
4
5
|
module Rollbar
|
5
6
|
class Item
|
@@ -39,8 +40,51 @@ module Rollbar
|
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
43
|
+
# Prepare objects to be handled by the payload serializer.
|
44
|
+
#
|
45
|
+
# Hashes and Arrays are traversed. Then all types execpt strings and
|
46
|
+
# immediates are exported using #inspect. Sending the object itself to the
|
47
|
+
# serializer can result in large recursive expansions, especially in Rails
|
48
|
+
# environments with ActiveRecord, ActiveSupport, etc. on the stack.
|
49
|
+
# Other export options could be #to_s, #to_h, and #as_json. Several of these
|
50
|
+
# will omit the class name, or are not implemented for many types.
|
51
|
+
#
|
52
|
+
# #inspect has the advantage that it is specifically intended for debugging
|
53
|
+
# output. If the user wants more or different information in the payload
|
54
|
+
# about a specific type, #inspect is the correct place to implement it.
|
55
|
+
# Likewise the default implementation should be oriented toward usefulness
|
56
|
+
# in debugging.
|
57
|
+
#
|
58
|
+
# Because #inspect outputs a string, it can be handled well by the string
|
59
|
+
# truncation strategy for large payloads.
|
60
|
+
#
|
42
61
|
def prepare_value(value)
|
43
|
-
value.
|
62
|
+
return simple_value?(value) ? value : value.inspect unless value.is_a?(Hash) || value.is_a?(Array)
|
63
|
+
|
64
|
+
cloned_value = ::Rollbar::Util.deep_copy(value)
|
65
|
+
::Rollbar::Util.iterate_and_update_with_block(cloned_value) do |v|
|
66
|
+
simple_value?(v) ? v : v.inspect
|
67
|
+
end
|
68
|
+
|
69
|
+
cloned_value
|
70
|
+
end
|
71
|
+
|
72
|
+
def simple_classes
|
73
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
|
74
|
+
[String, Symbol, Integer, Float, TrueClass, FalseClass, NilClass]
|
75
|
+
else
|
76
|
+
[String, Symbol, Fixnum, Bignum, Float, TrueClass, FalseClass, NilClass] # rubocop:disable Lint/UnifiedInteger
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def simple_value?(value)
|
81
|
+
simple_classes.each do |klass|
|
82
|
+
# Use instance_of? so that subclasses and module containers will
|
83
|
+
# be treated like complex object types, not simple values.
|
84
|
+
return true if value.instance_of?(klass)
|
85
|
+
end
|
86
|
+
|
87
|
+
false
|
44
88
|
end
|
45
89
|
|
46
90
|
def scrub(hash)
|
data/lib/rollbar/item.rb
CHANGED
@@ -65,7 +65,6 @@ module Rollbar
|
|
65
65
|
def build
|
66
66
|
data = build_data
|
67
67
|
self.payload = {
|
68
|
-
'access_token' => configuration.access_token,
|
69
68
|
'data' => data
|
70
69
|
}
|
71
70
|
|
@@ -109,15 +108,11 @@ module Rollbar
|
|
109
108
|
# the risk just to send this diagnostic object. In versions < 4.1, ActiveSupport hooks
|
110
109
|
# Ruby's JSON.generate so deeply there's no workaround.
|
111
110
|
'not serialized in ActiveSupport < 4.1'
|
112
|
-
elsif configuration.use_async
|
113
|
-
#
|
114
|
-
# means it is actually performed by ActiveSupport
|
115
|
-
#
|
116
|
-
|
117
|
-
# it should at least be done by rollbar-gem itself. Much work has been done
|
118
|
-
# to avoid the bugs in ActiveSupport JSON. The async handlers are currently
|
119
|
-
# still subject to all those knnown issues.
|
120
|
-
'not serialized for async/delayed handlers'
|
111
|
+
elsif configuration.use_async && !configuration.async_json_payload
|
112
|
+
# The setting allows serialization to be performed by each handler,
|
113
|
+
# and this usually means it is actually performed by ActiveSupport,
|
114
|
+
# which cannot safely serialize this key.
|
115
|
+
'not serialized when async_json_payload is not set'
|
121
116
|
else
|
122
117
|
scrub(configuration.configured_options.configured)
|
123
118
|
end
|
@@ -141,11 +136,18 @@ module Rollbar
|
|
141
136
|
uuid = stringified_payload['data']['uuid']
|
142
137
|
host = stringified_payload['data'].fetch('server', {})['host']
|
143
138
|
|
139
|
+
original_error = {
|
140
|
+
:message => message,
|
141
|
+
:exception => exception,
|
142
|
+
:configuration => configuration,
|
143
|
+
:uuid => uuid,
|
144
|
+
:host => host
|
145
|
+
}
|
146
|
+
|
144
147
|
notifier.send_failsafe(
|
145
148
|
too_large_payload_string(attempts),
|
146
149
|
nil,
|
147
|
-
|
148
|
-
host
|
150
|
+
original_error
|
149
151
|
)
|
150
152
|
logger.error("[Rollbar] Payload too large to be sent for UUID #{uuid}: #{Rollbar::JSON.dump(payload)}")
|
151
153
|
end
|
@@ -187,13 +189,19 @@ module Rollbar
|
|
187
189
|
end
|
188
190
|
|
189
191
|
def build_extra
|
192
|
+
merged_extra = Util.deep_merge(scrub(extra), scrub(error_context))
|
193
|
+
|
190
194
|
if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
|
191
|
-
Util.deep_merge(scrub(custom_data),
|
195
|
+
Util.deep_merge(scrub(custom_data), merged_extra)
|
192
196
|
else
|
193
|
-
|
197
|
+
merged_extra.empty? ? nil : merged_extra # avoid putting an empty {} in the payload.
|
194
198
|
end
|
195
199
|
end
|
196
200
|
|
201
|
+
def error_context
|
202
|
+
exception.respond_to?(:rollbar_context) && exception.rollbar_context
|
203
|
+
end
|
204
|
+
|
197
205
|
def scrub(data)
|
198
206
|
return data unless data.is_a? Hash
|
199
207
|
|
data/lib/rollbar/json.rb
CHANGED
@@ -80,10 +80,18 @@ module Rollbar
|
|
80
80
|
return app_result unless response_string
|
81
81
|
|
82
82
|
env[JS_IS_INJECTED_KEY] = true
|
83
|
-
response = ::Rack::Response.new(response_string, app_result[0],
|
84
|
-
app_result[1])
|
85
83
|
|
86
|
-
|
84
|
+
status, headers, = app_result
|
85
|
+
headers['Content-Length'] = response_string.bytesize.to_s if headers.key?('Content-Length')
|
86
|
+
|
87
|
+
response = ::Rack::Response.new(response_string, status, headers)
|
88
|
+
|
89
|
+
finished = response.finish
|
90
|
+
|
91
|
+
# Rack < 2.x Response#finish returns self in array[2]. Rack >= 2.x returns self.body.
|
92
|
+
# Always return with the response object here regardless of rack version.
|
93
|
+
finished[2] = response
|
94
|
+
finished
|
87
95
|
end
|
88
96
|
|
89
97
|
def build_body_with_js(env, body, head_open_end)
|
@@ -116,6 +124,8 @@ module Rollbar
|
|
116
124
|
end
|
117
125
|
|
118
126
|
def config_js_tag(env)
|
127
|
+
require 'json'
|
128
|
+
|
119
129
|
js_config = Rollbar::Util.deep_copy(config[:options])
|
120
130
|
|
121
131
|
add_person_data(js_config, env)
|