exception_handling 2.17.0.pre.tstarck.1 → 3.0.0.pre.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.tool-versions +1 -1
- data/Appraisals +0 -6
- data/CHANGELOG.md +8 -7
- data/Gemfile +1 -3
- data/Gemfile.lock +47 -125
- data/README.md +2 -39
- data/exception_handling.gemspec +3 -9
- data/gemfiles/rails_5.gemfile +1 -3
- data/gemfiles/rails_6.gemfile +1 -3
- data/gemfiles/rails_7.gemfile +1 -3
- data/lib/exception_handling/logging_methods.rb +1 -7
- data/lib/exception_handling/testing.rb +0 -13
- data/lib/exception_handling/version.rb +1 -1
- data/lib/exception_handling.rb +30 -221
- data/spec/spec_helper.rb +9 -42
- data/spec/unit/exception_handling/escalate_callback_spec.rb +2 -2
- data/spec/unit/exception_handling_spec.rb +28 -430
- metadata +6 -75
- data/lib/exception_handling/mailer.rb +0 -70
- data/lib/exception_handling/methods.rb +0 -54
- data/lib/exception_handling/sensu.rb +0 -28
- data/spec/unit/exception_handling/mailer_spec.rb +0 -97
- data/spec/unit/exception_handling/methods_spec.rb +0 -105
- data/spec/unit/exception_handling/sensu_spec.rb +0 -51
- data/views/exception_handling/mailer/escalate_custom.html.erb +0 -17
- data/views/exception_handling/mailer/escalation_notification.html.erb +0 -17
- data/views/exception_handling/mailer/log_parser_exception_notification.html.erb +0 -82
data/lib/exception_handling.rb
CHANGED
@@ -5,12 +5,11 @@ require 'timeout'
|
|
5
5
|
require 'active_support'
|
6
6
|
require 'active_support/core_ext'
|
7
7
|
require 'contextual_logger'
|
8
|
+
require 'yaml'
|
8
9
|
|
9
10
|
require 'invoca/utils'
|
10
11
|
|
11
|
-
require 'exception_handling/
|
12
|
-
require 'exception_handling/sensu'
|
13
|
-
require 'exception_handling/methods'
|
12
|
+
require 'exception_handling/logging_methods'
|
14
13
|
require 'exception_handling/log_stub_error'
|
15
14
|
require 'exception_handling/exception_description'
|
16
15
|
require 'exception_handling/exception_catalog'
|
@@ -21,7 +20,6 @@ _ = ActiveSupport::HashWithIndifferentAccess
|
|
21
20
|
|
22
21
|
module ExceptionHandling # never included
|
23
22
|
class Warning < StandardError; end
|
24
|
-
class MailerTimeout < Timeout::Error; end
|
25
23
|
class ClientLoggingError < StandardError; end
|
26
24
|
|
27
25
|
SUMMARY_THRESHOLD = 5
|
@@ -30,29 +28,17 @@ module ExceptionHandling # never included
|
|
30
28
|
AUTHENTICATION_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION'].freeze
|
31
29
|
HONEYBADGER_STATUSES = [:success, :failure, :skipped].freeze
|
32
30
|
|
33
|
-
Deprecation3_0 = ActiveSupport::Deprecation.new('3.0', 'exception_handling')
|
34
|
-
|
35
31
|
class << self
|
36
32
|
|
37
33
|
#
|
38
34
|
# required settings
|
39
35
|
#
|
40
36
|
attr_writer :server_name
|
41
|
-
attr_writer :sender_address
|
42
|
-
attr_writer :exception_recipients
|
43
37
|
|
44
38
|
def server_name
|
45
39
|
@server_name or raise ArgumentError, "You must assign a value to #{name}.server_name"
|
46
40
|
end
|
47
41
|
|
48
|
-
def sender_address
|
49
|
-
@sender_address or raise ArgumentError, "You must assign a value to #{name}.sender_address"
|
50
|
-
end
|
51
|
-
|
52
|
-
def exception_recipients
|
53
|
-
@exception_recipients or raise ArgumentError, "You must assign a value to #{name}.exception_recipients"
|
54
|
-
end
|
55
|
-
|
56
42
|
def configured?
|
57
43
|
!@logger.nil?
|
58
44
|
end
|
@@ -62,90 +48,38 @@ module ExceptionHandling # never included
|
|
62
48
|
end
|
63
49
|
|
64
50
|
def logger=(logger)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
Deprecation3_0.deprecation_warning('implicit extend with ContextualLogger::LoggerMixin', 'extend your logger instance or include into your logger class first')
|
69
|
-
logger.extend(ContextualLogger::LoggerMixin)
|
70
|
-
end
|
51
|
+
logger.nil? || logger.is_a?(ContextualLogger::LoggerMixin) or raise ArgumentError,
|
52
|
+
"The logger must be a ContextualLogger::LoggerMixin, not a #{logger.class}"
|
53
|
+
@logger = logger
|
71
54
|
EscalateCallback.register_if_configured!
|
72
55
|
end
|
73
56
|
|
74
|
-
def default_metric_name(exception_data, exception, treat_like_warning
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
else
|
86
|
-
"exception"
|
87
|
-
end
|
88
|
-
|
89
|
-
"#{'exception_handling.' if include_prefix}#{metric_name}"
|
90
|
-
end
|
91
|
-
|
92
|
-
def default_honeybadger_metric_name(honeybadger_status)
|
93
|
-
metric_name = if honeybadger_status.in?(HONEYBADGER_STATUSES)
|
94
|
-
honeybadger_status
|
95
|
-
else
|
96
|
-
:unknown_status
|
97
|
-
end
|
98
|
-
"exception_handling.honeybadger.#{metric_name}"
|
57
|
+
def default_metric_name(exception_data, exception, treat_like_warning)
|
58
|
+
if exception_data['metric_name']
|
59
|
+
exception_data['metric_name']
|
60
|
+
elsif exception.is_a?(ExceptionHandling::Warning)
|
61
|
+
"warning"
|
62
|
+
elsif treat_like_warning
|
63
|
+
exception_name = "_#{exception.class.name.split('::').last}" if exception.present?
|
64
|
+
"unforwarded_exception#{exception_name}"
|
65
|
+
else
|
66
|
+
"exception"
|
67
|
+
end
|
99
68
|
end
|
100
69
|
|
101
70
|
#
|
102
71
|
# optional settings
|
103
72
|
#
|
104
73
|
attr_accessor :production_support_recipients
|
105
|
-
attr_accessor :
|
106
|
-
attr_accessor :email_environment
|
74
|
+
attr_accessor :environment
|
107
75
|
attr_accessor :custom_data_hook
|
108
76
|
attr_accessor :post_log_error_hook
|
109
77
|
attr_accessor :stub_handler
|
110
|
-
attr_accessor :sensu_host
|
111
|
-
attr_accessor :sensu_port
|
112
|
-
attr_accessor :sensu_prefix
|
113
|
-
attr_reader :honeybadger_log_context_tags
|
114
78
|
|
115
79
|
attr_reader :filter_list_filename
|
116
|
-
attr_reader :eventmachine_safe
|
117
|
-
attr_reader :eventmachine_synchrony
|
118
80
|
attr_reader :honeybadger_auto_tagger
|
119
81
|
|
120
82
|
@filter_list_filename = "./config/exception_filters.yml"
|
121
|
-
@email_environment = ""
|
122
|
-
@eventmachine_safe = false
|
123
|
-
@eventmachine_synchrony = false
|
124
|
-
@sensu_host = "127.0.0.1"
|
125
|
-
@sensu_port = 3030
|
126
|
-
@sensu_prefix = ""
|
127
|
-
|
128
|
-
# set this for operation within an eventmachine reactor
|
129
|
-
def eventmachine_safe=(bool)
|
130
|
-
if bool != true && bool != false
|
131
|
-
raise ArgumentError, "#{name}.eventmachine_safe must be a boolean."
|
132
|
-
end
|
133
|
-
|
134
|
-
if bool
|
135
|
-
require 'eventmachine'
|
136
|
-
require 'em/protocols/smtpclient'
|
137
|
-
end
|
138
|
-
@eventmachine_safe = bool
|
139
|
-
end
|
140
|
-
|
141
|
-
# set this for EM::Synchrony async operation
|
142
|
-
def eventmachine_synchrony=(bool)
|
143
|
-
if bool != true && bool != false
|
144
|
-
raise ArgumentError, "#{name}.eventmachine_synchrony must be a boolean."
|
145
|
-
end
|
146
|
-
|
147
|
-
@eventmachine_synchrony = bool
|
148
|
-
end
|
149
83
|
|
150
84
|
def filter_list_filename=(filename)
|
151
85
|
@filter_list_filename = filename
|
@@ -164,22 +98,6 @@ module ExceptionHandling # never included
|
|
164
98
|
end
|
165
99
|
# rubocop:enable Style/TrivialAccessors
|
166
100
|
|
167
|
-
# @param tag_name [String]
|
168
|
-
# @param path [Array]
|
169
|
-
def add_honeybadger_tag_from_log_context(tag_name, path:)
|
170
|
-
tag_name.is_a?(String) or raise ArgumentError, "tag_name must be a String, #{tag_name.inspect}"
|
171
|
-
path.is_a?(Array) or raise ArgumentError, "path must be an Array, #{path.inspect}"
|
172
|
-
@honeybadger_log_context_tags ||= {}
|
173
|
-
if @honeybadger_log_context_tags.key?(tag_name)
|
174
|
-
log_warning("Overwriting existing tag path for '#{tag_name}' from #{@honeybadger_log_context_tags[tag_name]} to #{path}")
|
175
|
-
end
|
176
|
-
@honeybadger_log_context_tags[tag_name] = path
|
177
|
-
end
|
178
|
-
|
179
|
-
def clear_honeybadger_tags_from_log_context
|
180
|
-
@honeybadger_log_context_tags = nil
|
181
|
-
end
|
182
|
-
|
183
101
|
#
|
184
102
|
# internal settings (don't set directly)
|
185
103
|
#
|
@@ -299,7 +217,7 @@ module ExceptionHandling # never included
|
|
299
217
|
|
300
218
|
# Note: Both commas and spaces are treated as delimiters for the :tags string. Space-delimiters are not officially documented.
|
301
219
|
# https://github.com/honeybadger-io/honeybadger-ruby/pull/422
|
302
|
-
tags =
|
220
|
+
tags = (honeybadger_auto_tags(exception) + exception_info.honeybadger_tags).join(' ')
|
303
221
|
response = Honeybadger.notify(error_class: exception_description ? exception_description.filter_name : exception.class.name,
|
304
222
|
error_message: exception.message.to_s,
|
305
223
|
exception: exception,
|
@@ -313,6 +231,18 @@ module ExceptionHandling # never included
|
|
313
231
|
:failure
|
314
232
|
end
|
315
233
|
|
234
|
+
# @param exception [Exception]
|
235
|
+
#
|
236
|
+
# @return [Array<String>]
|
237
|
+
def honeybadger_auto_tags(exception)
|
238
|
+
@honeybadger_auto_tagger&.call(exception) || []
|
239
|
+
rescue => ex
|
240
|
+
traces = ex.backtrace.join("\n")
|
241
|
+
message = "Unable to execute honeybadger_auto_tags callback. #{ExceptionHandling.encode_utf8(ex.message.to_s)} #{traces}\n"
|
242
|
+
ExceptionHandling.log_info(message)
|
243
|
+
[]
|
244
|
+
end
|
245
|
+
|
316
246
|
#
|
317
247
|
# Check if Honeybadger defined.
|
318
248
|
#
|
@@ -366,51 +296,6 @@ module ExceptionHandling # never included
|
|
366
296
|
nil
|
367
297
|
end
|
368
298
|
|
369
|
-
def escalate_to_production_support(exception_or_string, email_subject)
|
370
|
-
production_support_recipients or raise ArgumentError, "In order to escalate to production support, you must set #{name}.production_recipients"
|
371
|
-
ex = make_exception(exception_or_string)
|
372
|
-
escalate(email_subject, ex, last_exception_timestamp, production_support_recipients)
|
373
|
-
end
|
374
|
-
|
375
|
-
def escalate_error(exception_or_string, email_subject, custom_recipients = nil, **log_context)
|
376
|
-
ex = make_exception(exception_or_string)
|
377
|
-
log_error(ex, **log_context)
|
378
|
-
escalate(email_subject, ex, last_exception_timestamp, custom_recipients)
|
379
|
-
end
|
380
|
-
|
381
|
-
def escalate_warning(message, email_subject, custom_recipients = nil, **log_context)
|
382
|
-
ex = Warning.new(message)
|
383
|
-
log_error(ex, **log_context)
|
384
|
-
escalate(email_subject, ex, last_exception_timestamp, custom_recipients)
|
385
|
-
end
|
386
|
-
|
387
|
-
def ensure_escalation(email_subject, custom_recipients = nil, **log_context)
|
388
|
-
yield
|
389
|
-
rescue => ex
|
390
|
-
escalate_error(ex, email_subject, custom_recipients, **log_context)
|
391
|
-
nil
|
392
|
-
end
|
393
|
-
|
394
|
-
deprecate :escalate_to_production_support, :escalate_error, :escalate_warning, :ensure_escalation,
|
395
|
-
deprecator: ActiveSupport::Deprecation.new('3.0', 'ExceptionHandling')
|
396
|
-
|
397
|
-
def alert_warning(exception_or_string, alert_name, exception_context, **log_context)
|
398
|
-
ex = make_exception(exception_or_string)
|
399
|
-
log_error(ex, exception_context, **log_context)
|
400
|
-
begin
|
401
|
-
ExceptionHandling::Sensu.generate_event(alert_name, exception_context.to_s + "\n" + encode_utf8(ex.message.to_s))
|
402
|
-
rescue => ex
|
403
|
-
log_error(ex, 'ExceptionHandling.alert_warning')
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
def ensure_alert(alert_name, exception_context, **log_context)
|
408
|
-
yield
|
409
|
-
rescue => ex
|
410
|
-
alert_warning(ex, alert_name, exception_context, **log_context)
|
411
|
-
nil
|
412
|
-
end
|
413
|
-
|
414
299
|
def set_log_error_timestamp
|
415
300
|
ExceptionHandling.last_exception_timestamp = Time.now.to_i
|
416
301
|
end
|
@@ -461,41 +346,6 @@ module ExceptionHandling # never included
|
|
461
346
|
|
462
347
|
private
|
463
348
|
|
464
|
-
# @param exception_info [ExceptionInfo]
|
465
|
-
#
|
466
|
-
# @return [Array<String>]
|
467
|
-
def tags_for_honeybadger(exception_info)
|
468
|
-
(
|
469
|
-
honeybadger_auto_tags(exception_info.exception) +
|
470
|
-
exception_info.honeybadger_tags +
|
471
|
-
honeybadger_tags_from_log_context(exception_info.honeybadger_context_data)
|
472
|
-
).uniq
|
473
|
-
end
|
474
|
-
|
475
|
-
# @param exception [Exception]
|
476
|
-
#
|
477
|
-
# @return [Array<String>]
|
478
|
-
def honeybadger_auto_tags(exception)
|
479
|
-
@honeybadger_auto_tagger&.call(exception) || []
|
480
|
-
rescue => ex
|
481
|
-
traces = ex.backtrace.join("\n")
|
482
|
-
message = "Unable to execute honeybadger_auto_tags callback. #{ExceptionHandling.encode_utf8(ex.message.to_s)} #{traces}\n"
|
483
|
-
ExceptionHandling.log_info(message)
|
484
|
-
[]
|
485
|
-
end
|
486
|
-
|
487
|
-
def honeybadger_tags_from_log_context(honeybadger_context_data)
|
488
|
-
if @honeybadger_log_context_tags
|
489
|
-
@honeybadger_log_context_tags.map do |tag_name, tag_path|
|
490
|
-
if (value_from_log_context = honeybadger_context_data.dig(:log_context, *tag_path))
|
491
|
-
"#{tag_name}:#{value_from_log_context}"
|
492
|
-
end
|
493
|
-
end.compact
|
494
|
-
else
|
495
|
-
[]
|
496
|
-
end
|
497
|
-
end
|
498
|
-
|
499
349
|
def execute_custom_log_error_callback(exception_data, exception, treat_like_warning, external_notification_results)
|
500
350
|
if ExceptionHandling.post_log_error_hook
|
501
351
|
honeybadger_status = external_notification_results[:honeybadger_status] || :skipped
|
@@ -508,47 +358,6 @@ module ExceptionHandling # never included
|
|
508
358
|
log_info("Unable to execute custom log_error callback. #{ex_message} #{ex_backtrace}")
|
509
359
|
end
|
510
360
|
|
511
|
-
def escalate(email_subject, ex, timestamp, custom_recipients = nil)
|
512
|
-
exception_info = ExceptionInfo.new(ex, nil, timestamp)
|
513
|
-
deliver(ExceptionHandling::Mailer.escalation_notification(email_subject, exception_info.data, custom_recipients))
|
514
|
-
end
|
515
|
-
|
516
|
-
def deliver(mail_object)
|
517
|
-
if ExceptionHandling.eventmachine_safe
|
518
|
-
EventMachine.schedule do # in case we're running outside the reactor
|
519
|
-
async_send_method = ExceptionHandling.eventmachine_synchrony ? :asend : :send
|
520
|
-
smtp_settings = ActionMailer::Base.smtp_settings
|
521
|
-
dns_deferrable = EventMachine::DNS::Resolver.resolve(smtp_settings[:address])
|
522
|
-
dns_deferrable.callback do |addrs|
|
523
|
-
send_deferrable = EventMachine::Protocols::SmtpClient.__send__(
|
524
|
-
async_send_method,
|
525
|
-
host: addrs.first,
|
526
|
-
port: smtp_settings[:port],
|
527
|
-
domain: smtp_settings[:domain],
|
528
|
-
auth: { type: :plain, username: smtp_settings[:user_name], password: smtp_settings[:password] },
|
529
|
-
from: mail_object['from'].to_s,
|
530
|
-
to: mail_object['to'].to_s,
|
531
|
-
content: "#{mail_object}\r\n.\r\n"
|
532
|
-
)
|
533
|
-
send_deferrable.errback { |err| ExceptionHandling.logger.fatal("Failed to email by SMTP: #{err.inspect}") }
|
534
|
-
end
|
535
|
-
dns_deferrable.errback { |err| ExceptionHandling.logger.fatal("Failed to resolv DNS for #{smtp_settings[:address]}: #{err.inspect}") }
|
536
|
-
end
|
537
|
-
else
|
538
|
-
safe_email_deliver do
|
539
|
-
mail_object.deliver_now
|
540
|
-
end
|
541
|
-
end
|
542
|
-
end
|
543
|
-
|
544
|
-
def safe_email_deliver
|
545
|
-
Timeout.timeout 30, MailerTimeout do
|
546
|
-
yield
|
547
|
-
end
|
548
|
-
rescue StandardError, MailerTimeout => ex
|
549
|
-
log_error(ex, "ExceptionHandling::safe_email_deliver", treat_like_warning: true)
|
550
|
-
end
|
551
|
-
|
552
361
|
def make_exception(exception_or_string)
|
553
362
|
if exception_or_string.is_a?(Exception)
|
554
363
|
exception_or_string
|
data/spec/spec_helper.rb
CHANGED
@@ -5,7 +5,6 @@ require 'rspec/mocks'
|
|
5
5
|
require 'rspec_junit_formatter'
|
6
6
|
|
7
7
|
require 'pry'
|
8
|
-
require 'pry-byebug'
|
9
8
|
require 'honeybadger'
|
10
9
|
require 'contextual_logger'
|
11
10
|
|
@@ -23,28 +22,20 @@ class LoggerStub
|
|
23
22
|
clear
|
24
23
|
end
|
25
24
|
|
26
|
-
def debug(message,
|
27
|
-
|
28
|
-
logged << { message: message, context: log_context, severity: 'DEBUG' }
|
29
|
-
end
|
25
|
+
def debug(message, log_context = {})
|
26
|
+
logged << { message: message, context: log_context, severity: 'DEBUG' }
|
30
27
|
end
|
31
28
|
|
32
|
-
def info(message,
|
33
|
-
|
34
|
-
logged << { message: message, context: log_context, severity: 'INFO' }
|
35
|
-
end
|
29
|
+
def info(message, log_context = {})
|
30
|
+
logged << { message: message, context: log_context, severity: 'INFO' }
|
36
31
|
end
|
37
32
|
|
38
|
-
def warn(message,
|
39
|
-
|
40
|
-
logged << { message: message, context: log_context, severity: 'WARN' }
|
41
|
-
end
|
33
|
+
def warn(message, log_context = {})
|
34
|
+
logged << { message: message, context: log_context, severity: 'WARN' }
|
42
35
|
end
|
43
36
|
|
44
|
-
def fatal(message,
|
45
|
-
|
46
|
-
logged << { message: message, context: log_context, severity: 'FATAL' }
|
47
|
-
end
|
37
|
+
def fatal(message, log_context = {})
|
38
|
+
logged << { message: message, context: log_context, severity: 'FATAL' }
|
48
39
|
end
|
49
40
|
|
50
41
|
def clear
|
@@ -83,16 +74,12 @@ def dont_stub_log_error
|
|
83
74
|
true
|
84
75
|
end
|
85
76
|
|
86
|
-
ActionMailer::Base.delivery_method = :test
|
87
|
-
|
88
|
-
|
89
77
|
module TestHelper
|
90
78
|
@constant_overrides = []
|
91
79
|
class << self
|
92
80
|
attr_accessor :constant_overrides
|
93
81
|
end
|
94
82
|
|
95
|
-
|
96
83
|
def setup_constant_overrides
|
97
84
|
unless TestHelper.constant_overrides.nil? || TestHelper.constant_overrides.empty?
|
98
85
|
raise "Uh-oh! constant_overrides left over: #{TestHelper.constant_overrides.inspect}"
|
@@ -100,19 +87,9 @@ module TestHelper
|
|
100
87
|
|
101
88
|
Time.now_override = nil
|
102
89
|
|
103
|
-
|
104
|
-
|
105
|
-
ExceptionHandling.email_environment = 'Test'
|
106
|
-
ExceptionHandling.sender_address = 'server@example.com'
|
107
|
-
ExceptionHandling.exception_recipients = 'exceptions@example.com'
|
108
|
-
ExceptionHandling.escalation_recipients = 'escalation@example.com'
|
90
|
+
ExceptionHandling.environment = 'not_test'
|
109
91
|
ExceptionHandling.server_name = 'server'
|
110
92
|
ExceptionHandling.filter_list_filename = "./config/exception_filters.yml"
|
111
|
-
ExceptionHandling.eventmachine_safe = false
|
112
|
-
ExceptionHandling.eventmachine_synchrony = false
|
113
|
-
ExceptionHandling.sensu_host = "127.0.0.1"
|
114
|
-
ExceptionHandling.sensu_port = 3030
|
115
|
-
ExceptionHandling.sensu_prefix = ""
|
116
93
|
end
|
117
94
|
|
118
95
|
def teardown_constant_overrides
|
@@ -151,16 +128,6 @@ module TestHelper
|
|
151
128
|
|
152
129
|
silence_warnings { final_parent_module.const_set(final_const_name, value) }
|
153
130
|
end
|
154
|
-
|
155
|
-
def assert_emails(expected, message = nil)
|
156
|
-
if block_given?
|
157
|
-
original_count = ActionMailer::Base.deliveries.size
|
158
|
-
yield
|
159
|
-
else
|
160
|
-
original_count = 0
|
161
|
-
end
|
162
|
-
expect(ActionMailer::Base.deliveries.size - original_count).to eq(expected), "wrong number of emails#{': ' + message.to_s if message}"
|
163
|
-
end
|
164
131
|
end
|
165
132
|
|
166
133
|
def assert_equal_with_diff(arg1, arg2, msg = '')
|
@@ -33,7 +33,7 @@ module ExceptionHandling
|
|
33
33
|
context 'when already configured' do
|
34
34
|
before do
|
35
35
|
@original_logger = ExceptionHandling.logger
|
36
|
-
ExceptionHandling.logger = ::Logger.new('/dev/null')
|
36
|
+
ExceptionHandling.logger = ::Logger.new('/dev/null').extend(ContextualLogger::LoggerMixin)
|
37
37
|
end
|
38
38
|
|
39
39
|
after do
|
@@ -66,7 +66,7 @@ module ExceptionHandling
|
|
66
66
|
|
67
67
|
expect(Escalate.on_escalate_callbacks).to be_empty
|
68
68
|
|
69
|
-
ExceptionHandling.logger = ::Logger.new('/dev/null')
|
69
|
+
ExceptionHandling.logger = ::Logger.new('/dev/null').extend(ContextualLogger::LoggerMixin)
|
70
70
|
expect(Escalate.on_escalate_callbacks).to_not be_empty
|
71
71
|
|
72
72
|
expect(logger).to_not receive(:error)
|