sentry-raven 2.12.1 → 3.0.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 +5 -5
- data/.craft.yml +14 -0
- data/.github/workflows/test.yml +77 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +44 -9
- data/.scripts/bump-version.sh +9 -0
- data/Gemfile +17 -25
- data/README.md +4 -3
- data/changelog.md +38 -0
- data/lib/raven/backtrace.rb +7 -5
- data/lib/raven/base.rb +5 -3
- data/lib/raven/breadcrumbs.rb +1 -1
- data/lib/raven/breadcrumbs/activesupport.rb +10 -10
- data/lib/raven/breadcrumbs/logger.rb +3 -3
- data/lib/raven/cli.rb +2 -2
- data/lib/raven/client.rb +12 -6
- data/lib/raven/configuration.rb +15 -5
- data/lib/raven/event.rb +5 -6
- data/lib/raven/instance.rb +6 -3
- data/lib/raven/integrations/delayed_job.rb +14 -15
- data/lib/raven/integrations/rack-timeout.rb +2 -3
- data/lib/raven/integrations/rack.rb +4 -3
- data/lib/raven/integrations/rails.rb +1 -0
- data/lib/raven/integrations/rails/active_job.rb +10 -7
- data/lib/raven/integrations/rails/overrides/debug_exceptions_catcher.rb +2 -2
- data/lib/raven/interface.rb +2 -2
- data/lib/raven/interfaces/stack_trace.rb +1 -1
- data/lib/raven/linecache.rb +5 -2
- data/lib/raven/logger.rb +3 -2
- data/lib/raven/processor/cookies.rb +16 -6
- data/lib/raven/processor/post_data.rb +2 -0
- data/lib/raven/processor/removecircularreferences.rb +1 -0
- data/lib/raven/processor/sanitizedata.rb +65 -17
- data/lib/raven/processor/utf8conversion.rb +2 -0
- data/lib/raven/transports.rb +4 -0
- data/lib/raven/transports/http.rb +5 -5
- data/lib/raven/utils/exception_cause_chain.rb +1 -0
- data/lib/raven/utils/real_ip.rb +1 -1
- data/lib/raven/version.rb +2 -2
- data/sentry-raven.gemspec +2 -2
- metadata +7 -12
- data/.travis.yml +0 -47
@@ -4,13 +4,13 @@ module Raven
|
|
4
4
|
module BreadcrumbLogger
|
5
5
|
LEVELS = {
|
6
6
|
::Logger::DEBUG => 'debug',
|
7
|
-
::Logger::INFO
|
8
|
-
::Logger::WARN
|
7
|
+
::Logger::INFO => 'info',
|
8
|
+
::Logger::WARN => 'warn',
|
9
9
|
::Logger::ERROR => 'error',
|
10
10
|
::Logger::FATAL => 'fatal'
|
11
11
|
}.freeze
|
12
12
|
|
13
|
-
EXC_FORMAT = /^([a-zA-Z0-9]+)\:\s(.*)
|
13
|
+
EXC_FORMAT = /^([a-zA-Z0-9]+)\:\s(.*)$/.freeze
|
14
14
|
|
15
15
|
def self.parse_exception(message)
|
16
16
|
lines = message.split(/\n\s*/)
|
data/lib/raven/cli.rb
CHANGED
data/lib/raven/client.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'base64'
|
3
4
|
require 'json'
|
4
5
|
require 'zlib'
|
5
6
|
|
7
|
+
require "raven/transports"
|
8
|
+
|
6
9
|
module Raven
|
7
10
|
# Encodes events and sends them to the Sentry server.
|
8
11
|
class Client
|
9
|
-
PROTOCOL_VERSION = '5'
|
10
|
-
USER_AGENT = "raven-ruby/#{Raven::VERSION}"
|
11
|
-
CONTENT_TYPE = 'application/json'
|
12
|
+
PROTOCOL_VERSION = '5'
|
13
|
+
USER_AGENT = "raven-ruby/#{Raven::VERSION}"
|
14
|
+
CONTENT_TYPE = 'application/json'
|
12
15
|
|
13
16
|
attr_accessor :configuration
|
14
17
|
|
@@ -35,7 +38,8 @@ module Raven
|
|
35
38
|
return
|
36
39
|
end
|
37
40
|
|
38
|
-
|
41
|
+
event_id = event[:event_id] || event['event_id']
|
42
|
+
configuration.logger.info "Sending event #{event_id} to Sentry"
|
39
43
|
|
40
44
|
content_type, encoded_data = encode(event)
|
41
45
|
|
@@ -92,7 +96,7 @@ module Raven
|
|
92
96
|
end
|
93
97
|
|
94
98
|
def get_log_message(event)
|
95
|
-
(event && event[:message]) || get_message_from_exception(event) || '<no message value>'
|
99
|
+
(event && event[:message]) || (event && event['message']) || get_message_from_exception(event) || '<no message value>'
|
96
100
|
end
|
97
101
|
|
98
102
|
def generate_auth_header
|
@@ -119,7 +123,9 @@ module Raven
|
|
119
123
|
configuration.logger.warn "Not sending event due to previous failure(s)."
|
120
124
|
end
|
121
125
|
configuration.logger.warn("Failed to submit event: #{get_log_message(event)}")
|
122
|
-
|
126
|
+
|
127
|
+
# configuration.transport_failure_callback can be false & nil
|
128
|
+
configuration.transport_failure_callback.call(event) if configuration.transport_failure_callback # rubocop:disable Style/SafeNavigation
|
123
129
|
end
|
124
130
|
end
|
125
131
|
|
data/lib/raven/configuration.rb
CHANGED
@@ -236,6 +236,7 @@ module Raven
|
|
236
236
|
|
237
237
|
def server=(value)
|
238
238
|
return if value.nil?
|
239
|
+
|
239
240
|
uri = URI.parse(value)
|
240
241
|
uri_path = uri.path.split('/')
|
241
242
|
|
@@ -253,13 +254,14 @@ module Raven
|
|
253
254
|
|
254
255
|
# For anyone who wants to read the base server string
|
255
256
|
@server = "#{scheme}://#{host}"
|
256
|
-
@server
|
257
|
-
@server
|
257
|
+
@server += ":#{port}" unless port == { 'http' => 80, 'https' => 443 }[scheme]
|
258
|
+
@server += path
|
258
259
|
end
|
259
260
|
alias dsn= server=
|
260
261
|
|
261
262
|
def encoding=(encoding)
|
262
263
|
raise(Error, 'Unsupported encoding') unless %w(gzip json).include? encoding
|
264
|
+
|
263
265
|
@encoding = encoding
|
264
266
|
end
|
265
267
|
|
@@ -267,6 +269,7 @@ module Raven
|
|
267
269
|
unless value == false || value.respond_to?(:call)
|
268
270
|
raise(ArgumentError, "async must be callable (or false to disable)")
|
269
271
|
end
|
272
|
+
|
270
273
|
@async = value
|
271
274
|
end
|
272
275
|
|
@@ -274,6 +277,7 @@ module Raven
|
|
274
277
|
unless value == false || value.respond_to?(:call)
|
275
278
|
raise(ArgumentError, "transport_failure_callback must be callable (or false to disable)")
|
276
279
|
end
|
280
|
+
|
277
281
|
@transport_failure_callback = value
|
278
282
|
end
|
279
283
|
|
@@ -281,6 +285,7 @@ module Raven
|
|
281
285
|
unless value == false || value.respond_to?(:call)
|
282
286
|
raise ArgumentError, "should_capture must be callable (or false to disable)"
|
283
287
|
end
|
288
|
+
|
284
289
|
@should_capture = value
|
285
290
|
end
|
286
291
|
|
@@ -288,6 +293,7 @@ module Raven
|
|
288
293
|
unless value == false || value.respond_to?(:call)
|
289
294
|
raise ArgumentError, "before_send must be callable (or false to disable)"
|
290
295
|
end
|
296
|
+
|
291
297
|
@before_send = value
|
292
298
|
end
|
293
299
|
|
@@ -351,8 +357,8 @@ module Raven
|
|
351
357
|
detect_release_from_git ||
|
352
358
|
detect_release_from_capistrano ||
|
353
359
|
detect_release_from_heroku
|
354
|
-
rescue =>
|
355
|
-
logger.error "Error detecting release: #{
|
360
|
+
rescue => e
|
361
|
+
logger.error "Error detecting release: #{e.message}"
|
356
362
|
end
|
357
363
|
|
358
364
|
def excluded_exception?(incoming_exception)
|
@@ -418,18 +424,21 @@ module Raven
|
|
418
424
|
|
419
425
|
def capture_in_current_environment?
|
420
426
|
return true unless environments.any? && !environments.include?(current_environment)
|
427
|
+
|
421
428
|
@errors << "Not configured to send/capture in environment '#{current_environment}'"
|
422
429
|
false
|
423
430
|
end
|
424
431
|
|
425
432
|
def capture_allowed_by_callback?(message_or_exc)
|
426
|
-
return true if !should_capture || message_or_exc.nil? || should_capture.call(
|
433
|
+
return true if !should_capture || message_or_exc.nil? || should_capture.call(message_or_exc)
|
434
|
+
|
427
435
|
@errors << "should_capture returned false"
|
428
436
|
false
|
429
437
|
end
|
430
438
|
|
431
439
|
def valid?
|
432
440
|
return true if %w(server host path public_key project_id).all? { |k| public_send(k) }
|
441
|
+
|
433
442
|
if server
|
434
443
|
%w(server host path public_key project_id).map do |key|
|
435
444
|
@errors << "No #{key} specified" unless public_send(key)
|
@@ -442,6 +451,7 @@ module Raven
|
|
442
451
|
|
443
452
|
def sample_allowed?
|
444
453
|
return true if sample_rate == 1.0
|
454
|
+
|
445
455
|
if Random::DEFAULT.rand >= sample_rate
|
446
456
|
@errors << "Excluded by random sample"
|
447
457
|
false
|
data/lib/raven/event.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'socket'
|
3
4
|
require 'securerandom'
|
4
5
|
|
@@ -76,7 +77,7 @@ module Raven
|
|
76
77
|
end
|
77
78
|
|
78
79
|
def message
|
79
|
-
@interfaces[:logentry]
|
80
|
+
@interfaces[:logentry]&.unformatted_message
|
80
81
|
end
|
81
82
|
|
82
83
|
def message=(args)
|
@@ -96,12 +97,13 @@ module Raven
|
|
96
97
|
end
|
97
98
|
|
98
99
|
def level=(new_level) # needed to meet the Sentry spec
|
99
|
-
@level = new_level == "warn"
|
100
|
+
@level = new_level.to_s == "warn" ? :warning : new_level
|
100
101
|
end
|
101
102
|
|
102
103
|
def interface(name, value = nil, &block)
|
103
104
|
int = Interface.registered[name]
|
104
105
|
raise(Error, "Unknown interface: #{name}") unless int
|
106
|
+
|
105
107
|
@interfaces[int.sentry_alias] = int.new(value, &block) if value || block
|
106
108
|
@interfaces[int.sentry_alias]
|
107
109
|
end
|
@@ -228,10 +230,7 @@ module Raven
|
|
228
230
|
end
|
229
231
|
|
230
232
|
def async_json_processors
|
231
|
-
|
232
|
-
Raven::Processor::RemoveCircularReferences,
|
233
|
-
Raven::Processor::UTF8Conversion
|
234
|
-
].map { |v| v.new(self) }
|
233
|
+
configuration.processors.map { |v| v.new(self) }
|
235
234
|
end
|
236
235
|
|
237
236
|
def list_gem_specs
|
data/lib/raven/instance.rb
CHANGED
@@ -51,6 +51,7 @@ module Raven
|
|
51
51
|
# Tell the log that the client is good to go
|
52
52
|
def report_status
|
53
53
|
return if configuration.silence_ready
|
54
|
+
|
54
55
|
if configuration.capture_allowed?
|
55
56
|
logger.info "Raven #{VERSION} ready to catch errors"
|
56
57
|
else
|
@@ -111,15 +112,15 @@ module Raven
|
|
111
112
|
message_or_exc = obj.is_a?(String) ? "message" : "exception"
|
112
113
|
options[:configuration] = configuration
|
113
114
|
options[:context] = context
|
114
|
-
if
|
115
|
+
if evt = Event.send("from_" + message_or_exc, obj, options)
|
115
116
|
yield evt if block_given?
|
116
117
|
if configuration.async?
|
117
118
|
begin
|
118
119
|
# We have to convert to a JSON-like hash, because background job
|
119
120
|
# processors (esp ActiveJob) may not like weird types in the event hash
|
120
121
|
configuration.async.call(evt.to_json_compatible)
|
121
|
-
rescue =>
|
122
|
-
logger.error("async event sending failed: #{
|
122
|
+
rescue => e
|
123
|
+
logger.error("async event sending failed: #{e.message}")
|
123
124
|
send_event(evt, make_hint(obj))
|
124
125
|
end
|
125
126
|
else
|
@@ -184,6 +185,7 @@ module Raven
|
|
184
185
|
def tags_context(options = nil)
|
185
186
|
context.tags.merge!(options || {})
|
186
187
|
yield if block_given?
|
188
|
+
context.tags
|
187
189
|
ensure
|
188
190
|
context.tags.delete_if { |k, _| options.keys.include? k } if block_given?
|
189
191
|
end
|
@@ -198,6 +200,7 @@ module Raven
|
|
198
200
|
def extra_context(options = nil)
|
199
201
|
context.extra.merge!(options || {})
|
200
202
|
yield if block_given?
|
203
|
+
context.extra
|
201
204
|
ensure
|
202
205
|
context.extra.delete_if { |k, _| options.keys.include? k } if block_given?
|
203
206
|
end
|
@@ -8,19 +8,18 @@ module Delayed
|
|
8
8
|
begin
|
9
9
|
# Forward the call to the next callback in the callback chain
|
10
10
|
block.call(job, *args)
|
11
|
-
|
12
|
-
rescue Exception => exception
|
11
|
+
rescue Exception => e
|
13
12
|
# Log error to Sentry
|
14
13
|
extra = {
|
15
14
|
:delayed_job => {
|
16
|
-
:id
|
17
|
-
:priority
|
18
|
-
:attempts
|
19
|
-
:run_at
|
20
|
-
:locked_at
|
21
|
-
:locked_by
|
22
|
-
:queue
|
23
|
-
:created_at
|
15
|
+
:id => job.id.to_s,
|
16
|
+
:priority => job.priority,
|
17
|
+
:attempts => job.attempts,
|
18
|
+
:run_at => job.run_at,
|
19
|
+
:locked_at => job.locked_at,
|
20
|
+
:locked_by => job.locked_by,
|
21
|
+
:queue => job.queue,
|
22
|
+
:created_at => job.created_at
|
24
23
|
}
|
25
24
|
}
|
26
25
|
# last_error can be nil
|
@@ -32,16 +31,16 @@ module Delayed
|
|
32
31
|
if job.respond_to?('payload_object') && job.payload_object.respond_to?('job_data')
|
33
32
|
extra[:active_job] = job.payload_object.job_data
|
34
33
|
end
|
35
|
-
::Raven.capture_exception(
|
36
|
-
:logger
|
37
|
-
:tags
|
34
|
+
::Raven.capture_exception(e,
|
35
|
+
:logger => 'delayed_job',
|
36
|
+
:tags => {
|
38
37
|
:delayed_job_queue => job.queue,
|
39
|
-
:delayed_job_id => job.id
|
38
|
+
:delayed_job_id => job.id.to_s
|
40
39
|
},
|
41
40
|
:extra => extra)
|
42
41
|
|
43
42
|
# Make sure we propagate the failure!
|
44
|
-
raise
|
43
|
+
raise e
|
45
44
|
ensure
|
46
45
|
::Raven::Context.clear!
|
47
46
|
::Raven::BreadcrumbBuffer.clear!
|
@@ -14,6 +14,5 @@ module RackTimeoutExtensions
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
Rack::Timeout::
|
19
|
-
Rack::Timeout::RequestTimeoutException.__send__(:include, RackTimeoutExtensions)
|
17
|
+
Rack::Timeout::Error.include(RackTimeoutExtensions)
|
18
|
+
Rack::Timeout::RequestTimeoutException.include(RackTimeoutExtensions)
|
@@ -92,8 +92,8 @@ module Raven
|
|
92
92
|
request.body.rewind
|
93
93
|
data
|
94
94
|
end
|
95
|
-
rescue IOError =>
|
96
|
-
|
95
|
+
rescue IOError => e
|
96
|
+
e.message
|
97
97
|
end
|
98
98
|
|
99
99
|
def format_headers_for_sentry(env_hash)
|
@@ -112,8 +112,9 @@ module Raven
|
|
112
112
|
next if key == 'HTTP_COOKIE' # Cookies don't go here, they go somewhere else
|
113
113
|
|
114
114
|
next unless key.start_with?('HTTP_') || %w(CONTENT_TYPE CONTENT_LENGTH).include?(key)
|
115
|
+
|
115
116
|
# Rack stores headers as HTTP_WHAT_EVER, we need What-Ever
|
116
|
-
key = key.
|
117
|
+
key = key.sub(/^HTTP_/, "")
|
117
118
|
key = key.split('_').map(&:capitalize).join('-')
|
118
119
|
memo[key] = value
|
119
120
|
rescue StandardError => e
|
@@ -5,6 +5,7 @@ module Raven
|
|
5
5
|
require 'raven/integrations/rails/overrides/streaming_reporter'
|
6
6
|
require 'raven/integrations/rails/controller_methods'
|
7
7
|
require 'raven/integrations/rails/controller_transaction'
|
8
|
+
require 'raven/integrations/rack'
|
8
9
|
|
9
10
|
initializer "raven.use_rack_middleware" do |app|
|
10
11
|
app.config.middleware.insert 0, Raven::Rack
|
@@ -9,19 +9,22 @@ module Raven
|
|
9
9
|
def self.included(base)
|
10
10
|
base.class_eval do
|
11
11
|
around_perform do |job, block|
|
12
|
-
|
12
|
+
if already_supported_by_specific_integration?(job)
|
13
|
+
block.call
|
14
|
+
else
|
15
|
+
capture_and_reraise_with_sentry(job, block)
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
17
21
|
def capture_and_reraise_with_sentry(job, block)
|
18
22
|
block.call
|
19
|
-
rescue Exception =>
|
20
|
-
return if rescue_with_handler(
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
raise exception
|
23
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
24
|
+
return if rescue_with_handler(e)
|
25
|
+
|
26
|
+
Raven.capture_exception(e, :extra => raven_context(job))
|
27
|
+
raise e
|
25
28
|
ensure
|
26
29
|
Context.clear!
|
27
30
|
BreadcrumbBuffer.clear!
|
@@ -6,7 +6,7 @@ module Raven
|
|
6
6
|
begin
|
7
7
|
env = env_or_request.respond_to?(:env) ? env_or_request.env : env_or_request
|
8
8
|
Raven::Rack.capture_exception(exception, env)
|
9
|
-
rescue
|
9
|
+
rescue
|
10
10
|
end
|
11
11
|
super
|
12
12
|
end
|
@@ -21,7 +21,7 @@ module Raven
|
|
21
21
|
begin
|
22
22
|
env = env_or_request.respond_to?(:env) ? env_or_request.env : env_or_request
|
23
23
|
Raven::Rack.capture_exception(exception, env)
|
24
|
-
rescue
|
24
|
+
rescue
|
25
25
|
end
|
26
26
|
render_exception_without_raven(env_or_request, exception)
|
27
27
|
end
|
data/lib/raven/interface.rb
CHANGED
data/lib/raven/linecache.rb
CHANGED
@@ -10,6 +10,7 @@ module Raven
|
|
10
10
|
# line should be the line requested by lineno. See specs for more information.
|
11
11
|
def get_file_context(filename, lineno, context)
|
12
12
|
return nil, nil, nil unless valid_path?(filename)
|
13
|
+
|
13
14
|
lines = Array.new(2 * context + 1) do |i|
|
14
15
|
getline(filename, lineno - context + i)
|
15
16
|
end
|
@@ -26,15 +27,17 @@ module Raven
|
|
26
27
|
def getlines(path)
|
27
28
|
@cache[path] ||= begin
|
28
29
|
IO.readlines(path)
|
29
|
-
|
30
|
-
|
30
|
+
rescue
|
31
|
+
nil
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
35
|
def getline(path, n)
|
35
36
|
return nil if n < 1
|
37
|
+
|
36
38
|
lines = getlines(path)
|
37
39
|
return nil if lines.nil?
|
40
|
+
|
38
41
|
lines[n - 1]
|
39
42
|
end
|
40
43
|
end
|