sentry-raven 2.12.2 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.craft.yml +15 -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 +37 -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 +4 -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
|
@@ -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
|
data/lib/raven/logger.rb
CHANGED