exception_handling 2.17.0.pre.tstarck.1 → 3.0.0.pre.2
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/.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
@@ -110,7 +110,6 @@ describe ExceptionHandling do
|
|
110
110
|
before(:each) do
|
111
111
|
# Reset this for every test since they are applied to the class
|
112
112
|
ExceptionHandling.honeybadger_auto_tagger = nil
|
113
|
-
ExceptionHandling.clear_honeybadger_tags_from_log_context
|
114
113
|
end
|
115
114
|
|
116
115
|
context "with warn and honeybadger notify stubbed" do
|
@@ -132,19 +131,9 @@ describe ExceptionHandling do
|
|
132
131
|
expect(ExceptionHandling.logger.singleton_class.ancestors.*.name).to eq(ancestors)
|
133
132
|
end
|
134
133
|
|
135
|
-
it "allows logger = nil
|
136
|
-
expect(STDERR).to receive(:puts).with(/DEPRECATION WARNING/).never
|
134
|
+
it "allows logger = nil" do
|
137
135
|
ExceptionHandling.logger = nil
|
138
|
-
|
139
|
-
|
140
|
-
it "[deprecated] mixes in ContextualLogger::Mixin if not there" do
|
141
|
-
expect(STDERR).to receive(:puts).with(/DEPRECATION WARNING: implicit extend with ContextualLogger::LoggerMixin is deprecated and will be removed from exception_handling 3\.0/)
|
142
|
-
logger = Logger.new('/dev/null')
|
143
|
-
ancestors = logger.singleton_class.ancestors.*.name
|
144
|
-
|
145
|
-
ExceptionHandling.logger = logger
|
146
|
-
expect(ExceptionHandling.logger).to be_kind_of(ContextualLogger::LoggerMixin)
|
147
|
-
expect(ExceptionHandling.logger.singleton_class.ancestors.*.name).to_not eq(ancestors)
|
136
|
+
expect { ExceptionHandling.logger }.to raise_error(ArgumentError, "You must assign a value to ExceptionHandling.logger")
|
148
137
|
end
|
149
138
|
|
150
139
|
context "#log_error" do
|
@@ -317,144 +306,53 @@ describe ExceptionHandling do
|
|
317
306
|
|
318
307
|
context "Exception Handling" do
|
319
308
|
context "default_metric_name" do
|
320
|
-
context "
|
321
|
-
it "
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
context "when metric_name is present in exception_data" do
|
327
|
-
it "include metric_name in resulting metric name" do
|
328
|
-
exception = StandardError.new('this is an exception')
|
329
|
-
metric = ExceptionHandling.default_metric_name({ 'metric_name' => 'special_metric' }, exception, true, include_prefix: true)
|
330
|
-
expect(metric).to eq('exception_handling.special_metric')
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
context "when metric_name is not present in exception_data" do
|
335
|
-
it "return exception_handling.warning when using log warning" do
|
336
|
-
warning = ExceptionHandling::Warning.new('this is a warning')
|
337
|
-
metric = ExceptionHandling.default_metric_name({}, warning, false, include_prefix: true)
|
338
|
-
expect(metric).to eq('exception_handling.warning')
|
339
|
-
end
|
340
|
-
|
341
|
-
it "return exception_handling.exception when using log error" do
|
342
|
-
exception = StandardError.new('this is an exception')
|
343
|
-
metric = ExceptionHandling.default_metric_name({}, exception, false, include_prefix: true)
|
344
|
-
expect(metric).to eq('exception_handling.exception')
|
345
|
-
end
|
346
|
-
|
347
|
-
context "when using log error with treat_like_warning" do
|
348
|
-
it "return exception_handling.unforwarded_exception when exception not present" do
|
349
|
-
metric = ExceptionHandling.default_metric_name({}, nil, true, include_prefix: true)
|
350
|
-
expect(metric).to eq('exception_handling.unforwarded_exception')
|
351
|
-
end
|
352
|
-
|
353
|
-
it "return exception_handling.unforwarded_exception with exception classname when exception is present" do
|
354
|
-
module SomeModule
|
355
|
-
class SomeException < StandardError
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
exception = SomeModule::SomeException.new('this is an exception')
|
360
|
-
metric = ExceptionHandling.default_metric_name({}, exception, true, include_prefix: true)
|
361
|
-
expect(metric).to eq('exception_handling.unforwarded_exception_SomeException')
|
362
|
-
end
|
363
|
-
end
|
309
|
+
context "when metric_name is present in exception_data" do
|
310
|
+
it "include metric_name in resulting metric name" do
|
311
|
+
exception = StandardError.new('this is an exception')
|
312
|
+
metric = ExceptionHandling.default_metric_name({ 'metric_name' => 'special_metric' }, exception, true)
|
313
|
+
expect(metric).to eq('special_metric')
|
364
314
|
end
|
365
315
|
end
|
366
316
|
|
367
|
-
context "
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
expect(metric).to eq('special_metric')
|
373
|
-
end
|
317
|
+
context "when metric_name is not present in exception_data" do
|
318
|
+
it "return exception_handling.warning when using log warning" do
|
319
|
+
warning = ExceptionHandling::Warning.new('this is a warning')
|
320
|
+
metric = ExceptionHandling.default_metric_name({}, warning, false)
|
321
|
+
expect(metric).to eq('warning')
|
374
322
|
end
|
375
323
|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
end
|
324
|
+
it "return exception_handling.exception when using log error" do
|
325
|
+
exception = StandardError.new('this is an exception')
|
326
|
+
metric = ExceptionHandling.default_metric_name({}, exception, false)
|
327
|
+
expect(metric).to eq('exception')
|
328
|
+
end
|
382
329
|
|
383
|
-
|
384
|
-
|
385
|
-
metric
|
386
|
-
expect(metric).to eq('
|
330
|
+
context "when using log error with treat_like_warning" do
|
331
|
+
it "return exception_handling.unforwarded_exception when exception not present" do
|
332
|
+
metric = ExceptionHandling.default_metric_name({}, nil, true)
|
333
|
+
expect(metric).to eq('unforwarded_exception')
|
387
334
|
end
|
388
335
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
expect(metric).to eq('unforwarded_exception')
|
393
|
-
end
|
394
|
-
|
395
|
-
it "return exception_handling.unforwarded_exception with exception classname when exception is present" do
|
396
|
-
module SomeModule
|
397
|
-
class SomeException < StandardError
|
398
|
-
end
|
336
|
+
it "return exception_handling.unforwarded_exception with exception classname when exception is present" do
|
337
|
+
module SomeModule
|
338
|
+
class SomeException < StandardError
|
399
339
|
end
|
400
|
-
|
401
|
-
exception = SomeModule::SomeException.new('this is an exception')
|
402
|
-
metric = ExceptionHandling.default_metric_name({}, exception, true, include_prefix: false)
|
403
|
-
expect(metric).to eq('unforwarded_exception_SomeException')
|
404
340
|
end
|
341
|
+
|
342
|
+
exception = SomeModule::SomeException.new('this is an exception')
|
343
|
+
metric = ExceptionHandling.default_metric_name({}, exception, true)
|
344
|
+
expect(metric).to eq('unforwarded_exception_SomeException')
|
405
345
|
end
|
406
346
|
end
|
407
347
|
end
|
408
348
|
end
|
409
349
|
|
410
|
-
context "default_honeybadger_metric_name" do
|
411
|
-
it "return exception_handling.honeybadger.success when status is :success" do
|
412
|
-
metric = ExceptionHandling.default_honeybadger_metric_name(:success)
|
413
|
-
expect(metric).to eq('exception_handling.honeybadger.success')
|
414
|
-
end
|
415
|
-
|
416
|
-
it "return exception_handling.honeybadger.failure when status is :failure" do
|
417
|
-
metric = ExceptionHandling.default_honeybadger_metric_name(:failure)
|
418
|
-
expect(metric).to eq('exception_handling.honeybadger.failure')
|
419
|
-
end
|
420
|
-
|
421
|
-
it "return exception_handling.honeybadger.skipped when status is :skipped" do
|
422
|
-
metric = ExceptionHandling.default_honeybadger_metric_name(:skipped)
|
423
|
-
expect(metric).to eq('exception_handling.honeybadger.skipped')
|
424
|
-
end
|
425
|
-
|
426
|
-
it "return exception_handling.honeybadger.unknown_status when status is not recognized" do
|
427
|
-
metric = ExceptionHandling.default_honeybadger_metric_name(nil)
|
428
|
-
expect(metric).to eq('exception_handling.honeybadger.unknown_status')
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
350
|
context "ExceptionHandling.ensure_safe" do
|
433
351
|
it "log an exception with call stack if an exception is raised." do
|
434
352
|
expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, any_args)
|
435
353
|
ExceptionHandling.ensure_safe { raise ArgumentError, "blah" }
|
436
354
|
end
|
437
355
|
|
438
|
-
if ActionView::VERSION::MAJOR >= 5
|
439
|
-
it "log an exception with call stack if an ActionView template exception is raised." do
|
440
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/\(Error:\d+\) \nActionView::Template::Error: \(blah\):\n /, any_args)
|
441
|
-
ExceptionHandling.ensure_safe do
|
442
|
-
begin
|
443
|
-
# Rails 5 made the switch from ActionView::TemplateError taking in the original exception
|
444
|
-
# as an argument to using the $! global to extract the original exception
|
445
|
-
raise ArgumentError, "blah"
|
446
|
-
rescue
|
447
|
-
raise ActionView::TemplateError.new({})
|
448
|
-
end
|
449
|
-
end
|
450
|
-
end
|
451
|
-
else
|
452
|
-
it "log an exception with call stack if an ActionView template exception is raised." do
|
453
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/\(Error:\d+\) \nActionView::Template::Error: \(blah\):\n /, any_args)
|
454
|
-
ExceptionHandling.ensure_safe { raise ActionView::TemplateError.new({}, ArgumentError.new("blah")) }
|
455
|
-
end
|
456
|
-
end
|
457
|
-
|
458
356
|
it "should not log an exception if an exception is not raised." do
|
459
357
|
expect(ExceptionHandling.logger).to_not receive(:fatal)
|
460
358
|
ExceptionHandling.ensure_safe { ; }
|
@@ -533,99 +431,6 @@ describe ExceptionHandling do
|
|
533
431
|
end
|
534
432
|
end
|
535
433
|
|
536
|
-
context "ExceptionHandling.ensure_escalation" do
|
537
|
-
before do
|
538
|
-
capture_notifications
|
539
|
-
ActionMailer::Base.deliveries.clear
|
540
|
-
end
|
541
|
-
|
542
|
-
it "log the exception as usual and send the proper email" do
|
543
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, any_args)
|
544
|
-
ExceptionHandling.ensure_escalation("Favorite Feature") { raise ArgumentError, "blah" }
|
545
|
-
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
546
|
-
expect(sent_notifications.size).to eq(1), sent_notifications.inspect
|
547
|
-
|
548
|
-
email = ActionMailer::Base.deliveries.last
|
549
|
-
expect(email.subject).to eq("#{ExceptionHandling.email_environment} Escalation: Favorite Feature")
|
550
|
-
expect(email.body.to_s).to match('ArgumentError: blah')
|
551
|
-
expect(email.body.to_s).to match(ExceptionHandling.last_exception_timestamp.to_s)
|
552
|
-
end
|
553
|
-
|
554
|
-
it "should not escalate if an exception is not raised." do
|
555
|
-
expect(ExceptionHandling.logger).to_not receive(:fatal)
|
556
|
-
ExceptionHandling.ensure_escalation('Ignored') { ; }
|
557
|
-
expect(ActionMailer::Base.deliveries.count).to eq(0)
|
558
|
-
end
|
559
|
-
|
560
|
-
it "log if the escalation email cannot be sent" do
|
561
|
-
expect_any_instance_of(Mail::Message).to receive(:deliver).and_raise(RuntimeError.new, "Delivery Error")
|
562
|
-
log_fatals = []
|
563
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(any_args).at_least(:once) do |*args|
|
564
|
-
log_fatals << args
|
565
|
-
end
|
566
|
-
|
567
|
-
ExceptionHandling.ensure_escalation("ensure context") { raise ArgumentError, "first_test_exception" }
|
568
|
-
expect(log_fatals[0].first).to match(/ArgumentError.*first_test_exception/)
|
569
|
-
expect(log_fatals[1].first).to match(/safe_email_deliver.*Delivery Error/m)
|
570
|
-
|
571
|
-
expect(log_fatals.size).to eq(2), log_fatals.inspect
|
572
|
-
|
573
|
-
expect(sent_notifications.size).to eq(1), sent_notifications.inspect # still sent to honeybadger
|
574
|
-
end
|
575
|
-
|
576
|
-
it "allow the caller to specify custom recipients" do
|
577
|
-
custom_recipients = ['something@invoca.com']
|
578
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, any_args)
|
579
|
-
ExceptionHandling.ensure_escalation("Favorite Feature", custom_recipients) { raise ArgumentError, "blah" }
|
580
|
-
expect(ActionMailer::Base.deliveries.count).to eq(1)
|
581
|
-
expect(sent_notifications.size).to eq(1), sent_notifications.inspect
|
582
|
-
|
583
|
-
email = ActionMailer::Base.deliveries.last
|
584
|
-
expect(email.subject).to eq("#{ExceptionHandling.email_environment} Escalation: Favorite Feature")
|
585
|
-
expect(email.body.to_s).to match('ArgumentError: blah')
|
586
|
-
expect(email.body.to_s).to match(ExceptionHandling.last_exception_timestamp.to_s)
|
587
|
-
expect(email.to).to eq(custom_recipients)
|
588
|
-
end
|
589
|
-
end
|
590
|
-
|
591
|
-
context "ExceptionHandling.ensure_alert" do
|
592
|
-
it "log the exception as usual and fire a sensu event" do
|
593
|
-
expect(ExceptionHandling::Sensu).to receive(:generate_event).with("Favorite Feature", "test context\nblah")
|
594
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/\(blah\):\n.*exception_handling_spec\.rb/, any_args)
|
595
|
-
ExceptionHandling.ensure_alert('Favorite Feature', 'test context') { raise ArgumentError, "blah" }
|
596
|
-
end
|
597
|
-
|
598
|
-
it "should not send sensu event if an exception is not raised." do
|
599
|
-
expect(ExceptionHandling.logger).to_not receive(:fatal)
|
600
|
-
expect(ExceptionHandling::Sensu).to_not receive(:generate_event)
|
601
|
-
ExceptionHandling.ensure_alert('Ignored', 'test context') { ; }
|
602
|
-
end
|
603
|
-
|
604
|
-
it "log if the sensu event could not be sent" do
|
605
|
-
expect(ExceptionHandling::Sensu).to receive(:send_event).with(anything) { raise "Failed to send" }
|
606
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/first_test_exception/, any_args)
|
607
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/Failed to send/, any_args)
|
608
|
-
ExceptionHandling.ensure_alert("Not Used", 'test context') { raise ArgumentError, "first_test_exception" }
|
609
|
-
end
|
610
|
-
|
611
|
-
it "log if the exception message is nil" do
|
612
|
-
expect(ExceptionHandling::Sensu).to receive(:generate_event).with("some alert", "test context\n")
|
613
|
-
ExceptionHandling.ensure_alert('some alert', 'test context') { raise_exception_with_nil_message }
|
614
|
-
end
|
615
|
-
end
|
616
|
-
|
617
|
-
context "ExceptionHandling.escalate_to_production_support" do
|
618
|
-
it "notify production support" do
|
619
|
-
subject = "Runtime Error found!"
|
620
|
-
exception = RuntimeError.new("Test")
|
621
|
-
recipients = ["prodsupport@example.com"]
|
622
|
-
|
623
|
-
expect(ExceptionHandling).to receive(:production_support_recipients).and_return(recipients).exactly(2)
|
624
|
-
expect(ExceptionHandling).to receive(:escalate).with(subject, exception, ExceptionHandling.last_exception_timestamp, recipients)
|
625
|
-
ExceptionHandling.escalate_to_production_support(exception, subject)
|
626
|
-
end
|
627
|
-
end
|
628
|
-
|
629
434
|
context "exception timestamp" do
|
630
435
|
before do
|
631
436
|
Time.now_override = Time.parse('1986-5-21 4:17 am UTC')
|
@@ -1054,88 +859,6 @@ describe ExceptionHandling do
|
|
1054
859
|
ExceptionHandling.filter_list_filename = "./config/other_exception_filters.yml"
|
1055
860
|
expect(ExceptionHandling.exception_catalog).to_not eq(catalog)
|
1056
861
|
end
|
1057
|
-
|
1058
|
-
context "Exception Handling Mailer" do
|
1059
|
-
EXPECTED_SMTP_HASH =
|
1060
|
-
{
|
1061
|
-
host: '127.0.0.1',
|
1062
|
-
domain: 'localhost.localdomain',
|
1063
|
-
from: 'server@example.com',
|
1064
|
-
to: 'escalation@example.com'
|
1065
|
-
}.freeze
|
1066
|
-
|
1067
|
-
[[true, false], [true, true]].each do |em_flag, synchrony_flag|
|
1068
|
-
context "eventmachine_safe = #{em_flag} && eventmachine_synchrony = #{synchrony_flag}" do
|
1069
|
-
before do
|
1070
|
-
ExceptionHandling.eventmachine_safe = em_flag
|
1071
|
-
ExceptionHandling.eventmachine_synchrony = synchrony_flag
|
1072
|
-
EventMachineStub.block = nil
|
1073
|
-
set_test_const('EventMachine', EventMachineStub)
|
1074
|
-
set_test_const('EventMachine::Protocols', Module.new)
|
1075
|
-
set_test_const('EventMachine::DNS', Module.new)
|
1076
|
-
set_test_const('EventMachine::DNS::Resolver', DNSResolvStub)
|
1077
|
-
end
|
1078
|
-
|
1079
|
-
after do
|
1080
|
-
ExceptionHandling.eventmachine_safe = false
|
1081
|
-
ExceptionHandling.eventmachine_synchrony = false
|
1082
|
-
end
|
1083
|
-
|
1084
|
-
it "schedule EventMachine STMP when EventMachine defined" do
|
1085
|
-
ActionMailer::Base.deliveries.clear
|
1086
|
-
|
1087
|
-
set_test_const('EventMachine::Protocols::SmtpClient', SmtpClientStub)
|
1088
|
-
|
1089
|
-
ExceptionHandling.ensure_escalation("ensure message") { raise 'Exception to escalate!' }
|
1090
|
-
expect(EventMachineStub.block).to be_truthy
|
1091
|
-
EventMachineStub.block.call
|
1092
|
-
expect(DNSResolvStub.callback_block).to be_truthy
|
1093
|
-
DNSResolvStub.callback_block.call ['127.0.0.1']
|
1094
|
-
expect((SmtpClientStub.send_hash & EXPECTED_SMTP_HASH.keys).map_hash { |_k, v| v.to_s }) .to eq(EXPECTED_SMTP_HASH), SmtpClientStub.send_hash.inspect
|
1095
|
-
expect(SmtpClientStub.last_method).to eq((synchrony_flag ? :asend : :send))
|
1096
|
-
expect(SmtpClientStub.send_hash[:content]).to match(/Exception to escalate/)
|
1097
|
-
assert_emails 0, ActionMailer::Base.deliveries.*.to_s
|
1098
|
-
end
|
1099
|
-
|
1100
|
-
it "pass the content as a proper rfc 2822 message" do
|
1101
|
-
set_test_const('EventMachine::Protocols::SmtpClient', SmtpClientStub)
|
1102
|
-
ExceptionHandling.ensure_escalation("ensure message") { raise 'Exception to escalate!' }
|
1103
|
-
expect(EventMachineStub.block).to be_truthy
|
1104
|
-
EventMachineStub.block.call
|
1105
|
-
expect(DNSResolvStub.callback_block).to be_truthy
|
1106
|
-
DNSResolvStub.callback_block.call ['127.0.0.1']
|
1107
|
-
expect(content = SmtpClientStub.send_hash[:content]).to be_truthy
|
1108
|
-
expect(content).to match(/Content-Transfer-Encoding: 7bit/)
|
1109
|
-
expect(content).to match(/\r\n\.\r\n\z/)
|
1110
|
-
end
|
1111
|
-
|
1112
|
-
it "log fatal on EventMachine STMP errback" do
|
1113
|
-
ActionMailer::Base.deliveries.clear
|
1114
|
-
|
1115
|
-
set_test_const('EventMachine::Protocols::SmtpClient', SmtpClientErrbackStub)
|
1116
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/Exception to escalate/, any_args)
|
1117
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/Failed to email by SMTP: "credential mismatch"/)
|
1118
|
-
|
1119
|
-
ExceptionHandling.ensure_escalation("ensure message") { raise 'Exception to escalate!' }
|
1120
|
-
expect(EventMachineStub.block).to be_truthy
|
1121
|
-
EventMachineStub.block.call
|
1122
|
-
expect(DNSResolvStub.callback_block).to be_truthy
|
1123
|
-
DNSResolvStub.callback_block.call(['127.0.0.1'])
|
1124
|
-
SmtpClientErrbackStub.block.call("credential mismatch")
|
1125
|
-
expect((SmtpClientErrbackStub.send_hash & EXPECTED_SMTP_HASH.keys).map_hash { |_k, v| v.to_s }).to eq(EXPECTED_SMTP_HASH), SmtpClientErrbackStub.send_hash.inspect end
|
1126
|
-
|
1127
|
-
it "log fatal on EventMachine dns resolver errback" do
|
1128
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/Exception to escalate/, any_args)
|
1129
|
-
expect(ExceptionHandling.logger).to receive(:fatal).with(/Failed to resolv DNS for localhost: "softlayer sucks"/)
|
1130
|
-
|
1131
|
-
ExceptionHandling.ensure_escalation("ensure message") { raise 'Exception to escalate!' }
|
1132
|
-
expect(EventMachineStub.block).to be_truthy
|
1133
|
-
EventMachineStub.block.call
|
1134
|
-
DNSResolvStub.errback_block.call("softlayer sucks")
|
1135
|
-
end
|
1136
|
-
end
|
1137
|
-
end
|
1138
|
-
end
|
1139
862
|
end
|
1140
863
|
|
1141
864
|
context "Exception mapping" do
|
@@ -1306,133 +1029,8 @@ describe ExceptionHandling do
|
|
1306
1029
|
ExceptionHandling.log_error(exception, nil, honeybadger_tags: ["some-other-tag"])
|
1307
1030
|
end
|
1308
1031
|
end
|
1309
|
-
|
1310
|
-
describe "#add_honeybadger_tag_from_log_context" do
|
1311
|
-
subject(:add_hb_tag) { ExceptionHandling.add_honeybadger_tag_from_log_context(tag_name, path: path) }
|
1312
|
-
let(:tag_name) { "sample-tag" }
|
1313
|
-
let(:path) { ["sample", "path"] }
|
1314
|
-
|
1315
|
-
it "sets the honeybadger log context tags to the tag name and path" do
|
1316
|
-
add_hb_tag
|
1317
|
-
expect(ExceptionHandling.honeybadger_log_context_tags).to include("sample-tag" => ["sample", "path"])
|
1318
|
-
end
|
1319
|
-
|
1320
|
-
context "when path is not an array" do
|
1321
|
-
let(:path) { "not an array" }
|
1322
|
-
|
1323
|
-
it "raises an argument error" do
|
1324
|
-
expect { add_hb_tag }.to raise_error(ArgumentError, /path must be an Array/)
|
1325
|
-
end
|
1326
|
-
end
|
1327
|
-
|
1328
|
-
context "when tag_name is not a string" do
|
1329
|
-
let(:tag_name) { 1 }
|
1330
|
-
|
1331
|
-
it "raises an argument error" do
|
1332
|
-
expect { add_hb_tag }.to raise_error(ArgumentError, /tag_name must be a String/)
|
1333
|
-
end
|
1334
|
-
end
|
1335
|
-
|
1336
|
-
context "when there already exists a tag with the same name" do
|
1337
|
-
before(:each) do
|
1338
|
-
ExceptionHandling.add_honeybadger_tag_from_log_context(tag_name, path: ["other", "path"])
|
1339
|
-
end
|
1340
|
-
|
1341
|
-
it "overwrites the existing tag to the new one" do
|
1342
|
-
add_hb_tag
|
1343
|
-
expect(ExceptionHandling.honeybadger_log_context_tags).to include("sample-tag" => ["sample", "path"])
|
1344
|
-
end
|
1345
|
-
|
1346
|
-
it "logs a warning" do
|
1347
|
-
expect(ExceptionHandling.logger).to receive(:warn).with(/Overwriting existing tag path for 'sample-tag'/, **{})
|
1348
|
-
add_hb_tag
|
1349
|
-
end
|
1350
|
-
end
|
1351
|
-
end
|
1352
|
-
|
1353
|
-
describe "honey badger tags" do
|
1354
|
-
context "with log context tags" do
|
1355
|
-
before(:each) do
|
1356
|
-
ExceptionHandling.add_honeybadger_tag_from_log_context("kubernetes_context", path: ["kubernetes", "context"])
|
1357
|
-
end
|
1358
|
-
|
1359
|
-
context "when error is logged within a log context that matches the path" do
|
1360
|
-
it "notifies honeybadger with the tags from the log context" do
|
1361
|
-
ExceptionHandling.logger.with_context("kubernetes" => { "context" => "local" }) do
|
1362
|
-
expect(Honeybadger).to receive(:notify).with(hash_including({ tags: "kubernetes_context:local" }))
|
1363
|
-
ExceptionHandling.log_error(StandardError.new("Error"), nil)
|
1364
|
-
end
|
1365
|
-
end
|
1366
|
-
end
|
1367
|
-
|
1368
|
-
context "when error is logged within a log context that doesn't match the path" do
|
1369
|
-
it "does not specify any tags in the honeybadger notify" do
|
1370
|
-
ExceptionHandling.logger.with_context("kubernetes" => { "pod" => "frontend-abc" }) do
|
1371
|
-
expect(Honeybadger).to receive(:notify).with(hash_including({ tags: "" }))
|
1372
|
-
ExceptionHandling.log_error(StandardError.new("Error"), nil)
|
1373
|
-
end
|
1374
|
-
end
|
1375
|
-
end
|
1376
|
-
|
1377
|
-
context "when error is logged outside of a log context block" do
|
1378
|
-
it "does not specify any tags in the honeybadger notify" do
|
1379
|
-
expect(Honeybadger).to receive(:notify).with(hash_including({ tags: "" }))
|
1380
|
-
ExceptionHandling.log_error(StandardError.new("Error"), nil)
|
1381
|
-
end
|
1382
|
-
end
|
1383
|
-
end
|
1384
|
-
|
1385
|
-
context "with all different honeybadger tagging" do
|
1386
|
-
subject(:log_error) { ExceptionHandling.log_error(StandardError.new("Error"), nil, honeybadger_tags: inline_tags) }
|
1387
|
-
let(:inline_tags) { ["inline-tag"] }
|
1388
|
-
before(:each) do
|
1389
|
-
ExceptionHandling.honeybadger_auto_tagger = ->(_exception) { ["auto-tag"] }
|
1390
|
-
ExceptionHandling.add_honeybadger_tag_from_log_context("log-context", path: ["inside", "context"])
|
1391
|
-
end
|
1392
|
-
|
1393
|
-
it "combines all the tags from different sources" do
|
1394
|
-
expect(Honeybadger).to receive(:notify).with(hash_including({ tags: "auto-tag inline-tag log-context:tag" }))
|
1395
|
-
ExceptionHandling.logger.with_context("inside" => { "context" => "tag" }) do
|
1396
|
-
log_error
|
1397
|
-
end
|
1398
|
-
end
|
1399
|
-
|
1400
|
-
context "when there are duplicate tags" do
|
1401
|
-
let(:inline_tags) { ["auto-tag"] }
|
1402
|
-
|
1403
|
-
it "notifies honeybadger with the set of tags" do
|
1404
|
-
expect(Honeybadger).to receive(:notify).with(hash_including({ tags: "auto-tag log-context:tag" }))
|
1405
|
-
ExceptionHandling.logger.with_context("inside" => { "context" => "tag" }) do
|
1406
|
-
log_error
|
1407
|
-
end
|
1408
|
-
end
|
1409
|
-
end
|
1410
|
-
end
|
1411
|
-
end
|
1412
1032
|
end
|
1413
1033
|
|
1414
|
-
context "ExceptionHandling < 3.0 " do
|
1415
|
-
it "should return a deprecation warning" do
|
1416
|
-
ExceptionHandling.production_support_recipients = "prodsupport@example.com"
|
1417
|
-
expect { ExceptionHandling.escalate_to_production_support("blah", "invoca@example.com") }
|
1418
|
-
.to output(/DEPRECATION WARNING: escalate_to_production_support is deprecated and will be removed from ExceptionHandling 3.0/).to_stderr
|
1419
|
-
end
|
1420
|
-
|
1421
|
-
it "should return a deprecation warning" do
|
1422
|
-
expect { ExceptionHandling.escalate_error("blah", "invoca@example.com") }
|
1423
|
-
.to output(/DEPRECATION WARNING: escalate_error is deprecated and will be removed from ExceptionHandling 3.0/).to_stderr
|
1424
|
-
end
|
1425
|
-
|
1426
|
-
it "should return a deprecation warning" do
|
1427
|
-
expect { ExceptionHandling.escalate_warning("blah", "invoca@example.com") }
|
1428
|
-
.to output(/DEPRECATION WARNING: escalate_warning is deprecated and will be removed from ExceptionHandling 3.0/).to_stderr
|
1429
|
-
end
|
1430
|
-
|
1431
|
-
it "should return a deprecation warning" do
|
1432
|
-
expect { ExceptionHandling.ensure_escalation("blah", "invoca@example.com") }
|
1433
|
-
.to output(/DEPRECATION WARNING: ensure_escalation is deprecated and will be removed from ExceptionHandling 3.0/).to_stderr
|
1434
|
-
end
|
1435
|
-
end
|
1436
1034
|
|
1437
1035
|
private
|
1438
1036
|
|
metadata
CHANGED
@@ -1,43 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_handling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0.pre.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Invoca
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: actionmailer
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '5.2'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '5.2'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: actionpack
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '5.2'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '5.2'
|
41
13
|
- !ruby/object:Gem::Dependency
|
42
14
|
name: activesupport
|
43
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,20 +52,6 @@ dependencies:
|
|
80
52
|
- - "~>"
|
81
53
|
- !ruby/object:Gem::Version
|
82
54
|
version: '0.3'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: eventmachine
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '1.0'
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '1.0'
|
97
55
|
- !ruby/object:Gem::Dependency
|
98
56
|
name: invoca-utils
|
99
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,21 +80,7 @@ dependencies:
|
|
122
80
|
- - "~>"
|
123
81
|
- !ruby/object:Gem::Version
|
124
82
|
version: '3.0'
|
125
|
-
|
126
|
-
name: net-smtp
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :runtime
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
|
-
description: Exception handling logger/emailer
|
83
|
+
description: Exception handling logger
|
140
84
|
email:
|
141
85
|
- development@invoca.com
|
142
86
|
executables: []
|
@@ -169,9 +113,6 @@ files:
|
|
169
113
|
- lib/exception_handling/exception_info.rb
|
170
114
|
- lib/exception_handling/log_stub_error.rb
|
171
115
|
- lib/exception_handling/logging_methods.rb
|
172
|
-
- lib/exception_handling/mailer.rb
|
173
|
-
- lib/exception_handling/methods.rb
|
174
|
-
- lib/exception_handling/sensu.rb
|
175
116
|
- lib/exception_handling/testing.rb
|
176
117
|
- lib/exception_handling/version.rb
|
177
118
|
- spec/helpers/controller_helpers.rb
|
@@ -184,13 +125,7 @@ files:
|
|
184
125
|
- spec/unit/exception_handling/exception_info_spec.rb
|
185
126
|
- spec/unit/exception_handling/log_error_stub_spec.rb
|
186
127
|
- spec/unit/exception_handling/logging_methods_spec.rb
|
187
|
-
- spec/unit/exception_handling/mailer_spec.rb
|
188
|
-
- spec/unit/exception_handling/methods_spec.rb
|
189
|
-
- spec/unit/exception_handling/sensu_spec.rb
|
190
128
|
- spec/unit/exception_handling_spec.rb
|
191
|
-
- views/exception_handling/mailer/escalate_custom.html.erb
|
192
|
-
- views/exception_handling/mailer/escalation_notification.html.erb
|
193
|
-
- views/exception_handling/mailer/log_parser_exception_notification.html.erb
|
194
129
|
homepage: https://github.com/Invoca/exception_handling
|
195
130
|
licenses: []
|
196
131
|
metadata:
|
@@ -204,18 +139,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
204
139
|
requirements:
|
205
140
|
- - ">="
|
206
141
|
- !ruby/object:Gem::Version
|
207
|
-
version:
|
142
|
+
version: '0'
|
208
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
209
144
|
requirements:
|
210
145
|
- - ">"
|
211
146
|
- !ruby/object:Gem::Version
|
212
147
|
version: 1.3.1
|
213
148
|
requirements: []
|
214
|
-
rubygems_version: 3.
|
149
|
+
rubygems_version: 3.3.7
|
215
150
|
signing_key:
|
216
151
|
specification_version: 4
|
217
|
-
summary: Invoca's exception handling logger
|
218
|
-
Works with Rails or EventMachine or EventMachine+Synchrony.
|
152
|
+
summary: Invoca's exception handling logger layer, based on exception_notifier.
|
219
153
|
test_files:
|
220
154
|
- spec/helpers/controller_helpers.rb
|
221
155
|
- spec/helpers/exception_helpers.rb
|
@@ -227,7 +161,4 @@ test_files:
|
|
227
161
|
- spec/unit/exception_handling/exception_info_spec.rb
|
228
162
|
- spec/unit/exception_handling/log_error_stub_spec.rb
|
229
163
|
- spec/unit/exception_handling/logging_methods_spec.rb
|
230
|
-
- spec/unit/exception_handling/mailer_spec.rb
|
231
|
-
- spec/unit/exception_handling/methods_spec.rb
|
232
|
-
- spec/unit/exception_handling/sensu_spec.rb
|
233
164
|
- spec/unit/exception_handling_spec.rb
|