exception_handling 2.5.0.pre.1 → 2.7.0.pre.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/CHANGELOG.md +29 -2
- data/Gemfile.lock +3 -3
- data/lib/exception_handling.rb +10 -4
- data/lib/exception_handling/exception_info.rb +4 -5
- data/lib/exception_handling/logging_methods.rb +33 -0
- data/lib/exception_handling/methods.rb +6 -53
- data/lib/exception_handling/testing.rb +20 -10
- data/lib/exception_handling/version.rb +1 -1
- data/test/rake_test_warning_false.rb +20 -0
- data/test/test_helper.rb +7 -3
- data/test/unit/exception_handling/exception_info_test.rb +22 -1
- data/test/unit/exception_handling/logging_methods_test.rb +37 -0
- data/test/unit/exception_handling/methods_test.rb +29 -8
- data/test/unit/exception_handling_test.rb +160 -67
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3794611262e09346bab80e7a683f4ce1d78d6ba04b46fa15fa4bc84ac087e41e
|
4
|
+
data.tar.gz: 36f96bed7f2b3375df4730d35ee5ec96cdf70e7c07f4ba589e187c75275c1736
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d1dad10749b867696c0f4dcacedcfb4af466ba792fa0c98ae307ee4bbeda10657f172fc95ff3c9b0162d1787d39c3c2a15a220fa6c6f4a7f7b10d857dad5eec
|
7
|
+
data.tar.gz: 8b28f2829a1e34787d7de51fdee4d0fe5a39356584d6d910c106edac2fe5d8ebcf0f3f5f1e9e1b7e4e7b0c36dd62035885214248072e47a7fdec7d1e4a854f94
|
data/CHANGELOG.md
CHANGED
@@ -4,11 +4,34 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
4
4
|
|
5
5
|
Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
-
## [2.
|
7
|
+
## [2.7.0] - Unreleased
|
8
|
+
### Added
|
9
|
+
- Added `LoggingMethods` as a replacement for `Methods` without setting controller or checking for long controller action.
|
10
|
+
### Deprecated
|
11
|
+
- Deprecated `Methods` in favor of `LoggingMethods`.
|
12
|
+
|
13
|
+
## [2.6.1] - Unreleased
|
14
|
+
### Fixed
|
15
|
+
- Fixed honeybadger_context_data to always merge `current_context_for_thread`, even if `log_context:` is passed as `nil`.
|
16
|
+
|
17
|
+
## [2.6.0] - 2020-08-26
|
18
|
+
### Changed
|
19
|
+
- Calling `log_warning` will now log with Severity::WARNING rather than FATAL.
|
20
|
+
- Reordered the logging to put the exception class next to the message.
|
21
|
+
|
22
|
+
## [2.5.0] - 2020-08-19
|
8
23
|
### Added
|
9
24
|
- The `**log_context` passed to `log_error`/`log_warning`/`log_info` is now
|
10
25
|
passed into `Honeybadger.notify()`, in `context: { log_context: ... }`.
|
11
26
|
|
27
|
+
### Fixed
|
28
|
+
- Silenced test warning noise by no longer running ruby -w.
|
29
|
+
- Renamed a constant to ALLOWLIST.
|
30
|
+
|
31
|
+
## [2.4.4] - 2020-08-10
|
32
|
+
### Fixed
|
33
|
+
- `ExceptionHandling.logger = nil` no longer displays an "implicit extend" deprecation warning.
|
34
|
+
|
12
35
|
## [2.4.3] - 2020-05-14
|
13
36
|
### Deprecated
|
14
37
|
- In `ExceptionHandling.logger=`, implicit `logger.extend ContextualLogger::LoggerMixin` is now deprecated.
|
@@ -29,7 +52,11 @@ Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0
|
|
29
52
|
### Changed
|
30
53
|
- No longer depends on hobo_support. Uses invoca-utils 0.3 instead.
|
31
54
|
|
32
|
-
[2.
|
55
|
+
[2.7.0]: https://github.com/Invoca/exception_handling/compare/v2.6.1...v2.7.0
|
56
|
+
[2.6.1]: https://github.com/Invoca/exception_handling/compare/v2.6.0...v2.6.1
|
57
|
+
[2.6.0]: https://github.com/Invoca/exception_handling/compare/v2.5.0...v2.6.0
|
58
|
+
[2.5.0]: https://github.com/Invoca/exception_handling/compare/v2.4.4...v2.5.0
|
59
|
+
[2.4.4]: https://github.com/Invoca/exception_handling/compare/v2.4.3...v2.4.4
|
33
60
|
[2.4.3]: https://github.com/Invoca/exception_handling/compare/v2.4.2...v2.4.3
|
34
61
|
[2.4.2]: https://github.com/Invoca/exception_handling/compare/v2.4.1...v2.4.2
|
35
62
|
[2.4.1]: https://github.com/Invoca/exception_handling/compare/v2.4.0...v2.4.1
|
data/Gemfile.lock
CHANGED
@@ -8,7 +8,7 @@ GIT
|
|
8
8
|
PATH
|
9
9
|
remote: .
|
10
10
|
specs:
|
11
|
-
exception_handling (2.
|
11
|
+
exception_handling (2.7.0.pre.1)
|
12
12
|
actionmailer (>= 4.2, < 7.0)
|
13
13
|
actionpack (>= 4.2, < 7.0)
|
14
14
|
activesupport (>= 4.2, < 7.0)
|
@@ -55,7 +55,7 @@ GEM
|
|
55
55
|
builder (3.2.3)
|
56
56
|
coderay (1.1.2)
|
57
57
|
concurrent-ruby (1.1.5)
|
58
|
-
contextual_logger (0.
|
58
|
+
contextual_logger (0.11.0)
|
59
59
|
activesupport
|
60
60
|
json
|
61
61
|
crass (1.0.6)
|
@@ -68,7 +68,7 @@ GEM
|
|
68
68
|
invoca-utils (0.4.1)
|
69
69
|
jaro_winkler (1.5.3)
|
70
70
|
json (2.3.1)
|
71
|
-
loofah (2.
|
71
|
+
loofah (2.7.0)
|
72
72
|
crass (~> 1.0.2)
|
73
73
|
nokogiri (>= 1.5.9)
|
74
74
|
mail (2.7.1)
|
data/lib/exception_handling.rb
CHANGED
@@ -29,6 +29,8 @@ module ExceptionHandling # never included
|
|
29
29
|
AUTHENTICATION_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION'].freeze
|
30
30
|
HONEYBADGER_STATUSES = [:success, :failure, :skipped].freeze
|
31
31
|
|
32
|
+
Deprecation3_0 = ActiveSupport::Deprecation.new('3.0', 'exception_handling')
|
33
|
+
|
32
34
|
class << self
|
33
35
|
|
34
36
|
#
|
@@ -54,10 +56,8 @@ module ExceptionHandling # never included
|
|
54
56
|
@logger or raise ArgumentError, "You must assign a value to #{name}.logger"
|
55
57
|
end
|
56
58
|
|
57
|
-
Deprecation3_0 = ActiveSupport::Deprecation.new('3.0', 'exception_handling')
|
58
|
-
|
59
59
|
def logger=(logger)
|
60
|
-
@logger = if logger.is_a?(ContextualLogger::LoggerMixin)
|
60
|
+
@logger = if logger.nil? || logger.is_a?(ContextualLogger::LoggerMixin)
|
61
61
|
logger
|
62
62
|
else
|
63
63
|
Deprecation3_0.deprecation_warning('implicit extend with ContextualLogger::LoggerMixin', 'extend your logger instance or include into your logger class first')
|
@@ -222,7 +222,13 @@ module ExceptionHandling # never included
|
|
222
222
|
#
|
223
223
|
def write_exception_to_log(ex, exception_context, timestamp, log_context = {})
|
224
224
|
ActiveSupport::Deprecation.silence do
|
225
|
-
|
225
|
+
log_message = "#{exception_context}\n#{ex.class}: (#{encode_utf8(ex.message.to_s)}):\n " + clean_backtrace(ex).join("\n ") + "\n\n"
|
226
|
+
|
227
|
+
if ex.is_a?(Warning)
|
228
|
+
ExceptionHandling.logger.warn("\nExceptionHandlingWarning (Warning:#{timestamp}) #{log_message}", log_context)
|
229
|
+
else
|
230
|
+
ExceptionHandling.logger.fatal("\nExceptionHandlingError (Error:#{timestamp}) #{log_message}", log_context)
|
231
|
+
end
|
226
232
|
end
|
227
233
|
end
|
228
234
|
|
@@ -57,7 +57,8 @@ module ExceptionHandling
|
|
57
57
|
@timestamp = timestamp
|
58
58
|
@controller = controller || controller_from_context(exception_context)
|
59
59
|
@data_callback = data_callback
|
60
|
-
|
60
|
+
# merge into the surrounding context just like ContextualLogger does when logging
|
61
|
+
@merged_log_context = ExceptionHandling.logger.current_context_for_thread.deep_merge(log_context || {})
|
61
62
|
end
|
62
63
|
|
63
64
|
def data
|
@@ -269,15 +270,13 @@ module ExceptionHandling
|
|
269
270
|
data = enhanced_data.dup
|
270
271
|
data[:server] = ExceptionHandling.server_name
|
271
272
|
data[:exception_context] = deep_clean_hash(@exception_context) if @exception_context.present?
|
272
|
-
data[:log_context] = @
|
273
|
+
data[:log_context] = @merged_log_context
|
273
274
|
unstringify_sections(data)
|
274
|
-
|
275
|
+
HONEYBADGER_CONTEXT_SECTIONS.each_with_object({}) do |section, context|
|
275
276
|
if data[section].present?
|
276
277
|
context[section] = data[section]
|
277
278
|
end
|
278
|
-
context
|
279
279
|
end
|
280
|
-
context_data
|
281
280
|
end
|
282
281
|
end
|
283
282
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
require 'active_support/core_ext/module/delegation.rb'
|
5
|
+
|
6
|
+
module ExceptionHandling
|
7
|
+
module LoggingMethods # included on models and controllers
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
delegate :log_error_rack, :log_warning, :log_info, :log_debug, :escalate_error, :escalate_warning, :ensure_escalation, :alert_warning, to: ExceptionHandling
|
13
|
+
|
14
|
+
# TODO: delegate log_error as well
|
15
|
+
def log_error(exception_or_string, exception_context = '')
|
16
|
+
controller = self if respond_to?(:request) && respond_to?(:session)
|
17
|
+
ExceptionHandling.log_error(exception_or_string, exception_context, controller)
|
18
|
+
end
|
19
|
+
|
20
|
+
def ensure_safe(exception_context = "")
|
21
|
+
yield
|
22
|
+
rescue => ex
|
23
|
+
log_error ex, exception_context
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def ensure_alert(*args)
|
28
|
+
ExceptionHandling.ensure_alert(*args) do
|
29
|
+
yield
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,65 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_support/concern'
|
4
|
+
require_relative 'logging_methods'
|
4
5
|
|
5
6
|
module ExceptionHandling
|
6
7
|
module Methods # included on models and controllers
|
7
8
|
extend ActiveSupport::Concern
|
9
|
+
include ExceptionHandling::LoggingMethods
|
8
10
|
|
9
11
|
protected
|
10
12
|
|
11
|
-
def log_error(exception_or_string, exception_context = '')
|
12
|
-
controller = self if respond_to?(:request) && respond_to?(:session)
|
13
|
-
ExceptionHandling.log_error(exception_or_string, exception_context, controller)
|
14
|
-
end
|
15
|
-
|
16
|
-
def log_error_rack(exception_or_string, exception_context = '', rack_filter = '')
|
17
|
-
ExceptionHandling.log_error_rack(exception_or_string, exception_context, rack_filter)
|
18
|
-
end
|
19
|
-
|
20
|
-
def log_warning(message)
|
21
|
-
ExceptionHandling.log_warning(message)
|
22
|
-
end
|
23
|
-
|
24
|
-
def log_info(message)
|
25
|
-
ExceptionHandling.logger.info(message)
|
26
|
-
end
|
27
|
-
|
28
|
-
def log_debug(message)
|
29
|
-
ExceptionHandling.logger.debug(message)
|
30
|
-
end
|
31
|
-
|
32
|
-
def ensure_safe(exception_context = "")
|
33
|
-
yield
|
34
|
-
rescue => ex
|
35
|
-
log_error ex, exception_context
|
36
|
-
nil
|
37
|
-
end
|
38
|
-
|
39
|
-
def escalate_error(exception_or_string, email_subject)
|
40
|
-
ExceptionHandling.escalate_error(exception_or_string, email_subject)
|
41
|
-
end
|
42
|
-
|
43
|
-
def escalate_warning(message, email_subject)
|
44
|
-
ExceptionHandling.escalate_warning(message, email_subject)
|
45
|
-
end
|
46
|
-
|
47
|
-
def ensure_escalation(*args)
|
48
|
-
ExceptionHandling.ensure_escalation(*args) do
|
49
|
-
yield
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def alert_warning(*args)
|
54
|
-
ExceptionHandling.alert_warning(*args)
|
55
|
-
end
|
56
|
-
|
57
|
-
def ensure_alert(*args)
|
58
|
-
ExceptionHandling.ensure_alert(*args) do
|
59
|
-
yield
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
13
|
def long_controller_action_timeout
|
64
14
|
if defined?(Rails) && Rails.respond_to?(:env) && Rails.env == 'test'
|
65
15
|
300
|
@@ -88,7 +38,10 @@ module ExceptionHandling
|
|
88
38
|
end
|
89
39
|
|
90
40
|
included do
|
91
|
-
around_filter
|
41
|
+
Deprecation3_0.deprecation_warning('ExceptionHandling::Methods', 'include LoggingMethods; in controllers, set your own around_filter to set logging context')
|
42
|
+
if respond_to? :around_filter
|
43
|
+
around_filter :set_current_controller
|
44
|
+
end
|
92
45
|
end
|
93
46
|
|
94
47
|
class_methods do
|
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
module ExceptionHandling
|
6
6
|
module Testing
|
7
|
-
class
|
7
|
+
class ControllerStubBase
|
8
8
|
|
9
9
|
class Request
|
10
10
|
attr_accessor :parameters, :protocol, :host, :request_uri, :env, :session_options
|
@@ -25,7 +25,7 @@ module ExceptionHandling
|
|
25
25
|
attr_accessor :around_filter_method
|
26
26
|
|
27
27
|
def around_filter(method)
|
28
|
-
|
28
|
+
self.around_filter_method = method
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -44,14 +44,6 @@ module ExceptionHandling
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def simulate_around_filter(&block)
|
48
|
-
set_current_controller(&block)
|
49
|
-
end
|
50
|
-
|
51
|
-
def controller_name
|
52
|
-
"ControllerStub"
|
53
|
-
end
|
54
|
-
|
55
47
|
def action_name
|
56
48
|
"test_action"
|
57
49
|
end
|
@@ -59,9 +51,27 @@ module ExceptionHandling
|
|
59
51
|
def complete_request_uri
|
60
52
|
"#{@request.protocol}#{@request.host}#{@request.request_uri}"
|
61
53
|
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class LoggingMethodsControllerStub < ControllerStubBase
|
57
|
+
include ExceptionHandling::LoggingMethods
|
58
|
+
|
59
|
+
def controller_name
|
60
|
+
"LoggingMethodsControllerStub"
|
61
|
+
end
|
62
|
+
end
|
62
63
|
|
64
|
+
class MethodsControllerStub < ControllerStubBase
|
63
65
|
include ExceptionHandling::Methods
|
64
66
|
set_long_controller_action_timeout 2
|
67
|
+
|
68
|
+
def simulate_around_filter(&block)
|
69
|
+
set_current_controller(&block)
|
70
|
+
end
|
71
|
+
|
72
|
+
def controller_name
|
73
|
+
"MethodsControllerStub"
|
74
|
+
end
|
65
75
|
end
|
66
76
|
end
|
67
77
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Rake 11+ has a misfeature where @warning = true by default
|
4
|
+
# See https://github.com/ruby/rake/pull/97/files
|
5
|
+
# This causes all tests to be run with `ruby -w`, causing a huge number of warnings
|
6
|
+
# from gems we don't control and overwhelming our test output.
|
7
|
+
# This patch reverts that.
|
8
|
+
|
9
|
+
_ = Rake::TestTask
|
10
|
+
|
11
|
+
class Rake::TestTask
|
12
|
+
module SetWarningFalseMixin
|
13
|
+
def initialize(*args)
|
14
|
+
super
|
15
|
+
self.warning = false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
prepend SetWarningFalseMixin
|
20
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -33,16 +33,20 @@ class LoggerStub
|
|
33
33
|
clear
|
34
34
|
end
|
35
35
|
|
36
|
+
def debug(message, log_context = {})
|
37
|
+
logged << { message: message, context: log_context, severity: 'DEBUG' }
|
38
|
+
end
|
39
|
+
|
36
40
|
def info(message, log_context = {})
|
37
|
-
logged << { message: message, context: log_context }
|
41
|
+
logged << { message: message, context: log_context, severity: 'INFO' }
|
38
42
|
end
|
39
43
|
|
40
44
|
def warn(message, log_context = {})
|
41
|
-
logged << { message: message, context: log_context }
|
45
|
+
logged << { message: message, context: log_context, severity: 'WARN' }
|
42
46
|
end
|
43
47
|
|
44
48
|
def fatal(message, log_context = {})
|
45
|
-
logged << { message: message, context: log_context }
|
49
|
+
logged << { message: message, context: log_context, severity: 'FATAL' }
|
46
50
|
end
|
47
51
|
|
48
52
|
def clear
|
@@ -417,6 +417,26 @@ module ExceptionHandling
|
|
417
417
|
end
|
418
418
|
|
419
419
|
context "honeybadger_context_data" do
|
420
|
+
setup do
|
421
|
+
stub(ExceptionHandling.logger).current_context_for_thread { { cuid: 'ABCD' } }
|
422
|
+
end
|
423
|
+
|
424
|
+
should "include thread_context when log_context: is nil" do
|
425
|
+
exception_with_nil_message = RuntimeError.new(nil)
|
426
|
+
stub(exception_with_nil_message).message { nil }
|
427
|
+
exception_info = ExceptionInfo.new(exception_with_nil_message, @exception_context, @timestamp)
|
428
|
+
honeybadger_context_data = exception_info.honeybadger_context_data
|
429
|
+
assert_equal({ "cuid" => 'ABCD' }, honeybadger_context_data[:log_context])
|
430
|
+
end
|
431
|
+
|
432
|
+
should "include thread context merged with log_context:" do
|
433
|
+
exception_with_nil_message = RuntimeError.new(nil)
|
434
|
+
stub(exception_with_nil_message).message { nil }
|
435
|
+
exception_info = ExceptionInfo.new(exception_with_nil_message, @exception_context, @timestamp, log_context: { url: 'http://example.com' })
|
436
|
+
honeybadger_context_data = exception_info.honeybadger_context_data
|
437
|
+
assert_equal({ "cuid" => 'ABCD', "url" => 'http://example.com' }, honeybadger_context_data[:log_context])
|
438
|
+
end
|
439
|
+
|
420
440
|
should "return the error details and relevant context data to be used as honeybadger notification context while filtering sensitive data" do
|
421
441
|
env = { server: "fe98" }
|
422
442
|
parameters = { advertiser_id: 435 }
|
@@ -464,7 +484,8 @@ module ExceptionHandling
|
|
464
484
|
"test/unit/exception_handling_test.rb:847:in `exception_1'",
|
465
485
|
"test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
|
466
486
|
],
|
467
|
-
event_response: "Event successfully received"
|
487
|
+
event_response: "Event successfully received",
|
488
|
+
log_context: { "cuid" => "ABCD" }
|
468
489
|
}
|
469
490
|
assert_equal_with_diff expected_data, exception_info.honeybadger_context_data
|
470
491
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../test_helper'
|
4
|
+
require_relative '../../helpers/exception_helpers'
|
5
|
+
|
6
|
+
require "exception_handling/testing"
|
7
|
+
|
8
|
+
module ExceptionHandling
|
9
|
+
class LoggingMethodsTest < ActiveSupport::TestCase
|
10
|
+
include ExceptionHelpers
|
11
|
+
|
12
|
+
def dont_stub_log_error
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
context "ExceptionHandling::LoggingMethods" do
|
17
|
+
setup do
|
18
|
+
@controller = Testing::LoggingMethodsControllerStub.new
|
19
|
+
ExceptionHandling.stub_handler = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
context "#log_warning" do
|
23
|
+
should "be available to the controller" do
|
24
|
+
klass = Class.new
|
25
|
+
klass.include ExceptionHandling::LoggingMethods
|
26
|
+
instance = klass.new
|
27
|
+
assert instance.methods.include?(:log_warning)
|
28
|
+
end
|
29
|
+
|
30
|
+
should "call ExceptionHandling#log_warning" do
|
31
|
+
mock(ExceptionHandling).log_warning("Hi mom")
|
32
|
+
@controller.send(:log_warning, "Hi mom")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative '../../test_helper'
|
4
|
+
require_relative '../../helpers/exception_helpers'
|
4
5
|
|
5
6
|
require "exception_handling/testing"
|
6
7
|
|
@@ -12,14 +13,14 @@ module ExceptionHandling
|
|
12
13
|
true
|
13
14
|
end
|
14
15
|
|
15
|
-
context "ExceptionHandling
|
16
|
+
context "ExceptionHandling::Methods" do
|
16
17
|
setup do
|
17
|
-
@controller = Testing::
|
18
|
+
@controller = Testing::MethodsControllerStub.new
|
18
19
|
ExceptionHandling.stub_handler = nil
|
19
20
|
end
|
20
21
|
|
21
22
|
should "set the around filter" do
|
22
|
-
assert_equal :set_current_controller, Testing::
|
23
|
+
assert_equal :set_current_controller, Testing::MethodsControllerStub.around_filter_method
|
23
24
|
assert_nil ExceptionHandling.current_controller
|
24
25
|
@controller.simulate_around_filter do
|
25
26
|
assert_equal @controller, ExceptionHandling.current_controller
|
@@ -70,15 +71,35 @@ module ExceptionHandling
|
|
70
71
|
|
71
72
|
context "#log_warning" do
|
72
73
|
should "be available to the controller" do
|
73
|
-
|
74
|
+
assert @controller.methods.include?(:log_warning)
|
74
75
|
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "included deprecation" do
|
80
|
+
setup do
|
81
|
+
mock_deprecation_3_0
|
82
|
+
end
|
75
83
|
|
76
|
-
|
77
|
-
|
78
|
-
|
84
|
+
should "deprecate when no around_filter in included hook" do
|
85
|
+
k = Class.new
|
86
|
+
k.include ExceptionHandling::Methods
|
87
|
+
end
|
88
|
+
|
89
|
+
should "deprecate controller around_filter in included hook" do
|
90
|
+
controller = Class.new
|
91
|
+
class << controller
|
92
|
+
def around_filter(*)
|
93
|
+
end
|
79
94
|
end
|
95
|
+
controller.include ExceptionHandling::Methods
|
80
96
|
end
|
81
97
|
end
|
82
98
|
|
99
|
+
private
|
100
|
+
|
101
|
+
def mock_deprecation_3_0
|
102
|
+
mock(STDERR).puts(/DEPRECATION WARNING: ExceptionHandling::Methods is deprecated and will be removed from exception_handling 3\.0/)
|
103
|
+
end
|
83
104
|
end
|
84
105
|
end
|
@@ -126,6 +126,11 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
126
126
|
assert_equal ancestors, ExceptionHandling.logger.singleton_class.ancestors.*.name
|
127
127
|
end
|
128
128
|
|
129
|
+
should "allow logger = nil (no deprecation warning)" do
|
130
|
+
mock(STDERR).puts(/DEPRECATION WARNING/).never
|
131
|
+
ExceptionHandling.logger = nil
|
132
|
+
end
|
133
|
+
|
129
134
|
should "[deprecated] mix in ContextualLogger::Mixin if not there" do
|
130
135
|
mock(STDERR).puts(/DEPRECATION WARNING: implicit extend with ContextualLogger::LoggerMixin is deprecated and will be removed from exception_handling 3\.0/)
|
131
136
|
logger = Logger.new('/dev/null')
|
@@ -144,6 +149,11 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
144
149
|
assert_not_empty logged_excluding_reload_filter.last[:context]
|
145
150
|
assert_equal logged_excluding_reload_filter.last[:context], service_name: 'exception_handling'
|
146
151
|
end
|
152
|
+
|
153
|
+
should "log with Severity::FATAL" do
|
154
|
+
ExceptionHandling.log_error('This is a Warning', service_name: 'exception_handling')
|
155
|
+
assert_equal logged_excluding_reload_filter.last[:severity], 'FATAL'
|
156
|
+
end
|
147
157
|
end
|
148
158
|
|
149
159
|
context "#log_warning" do
|
@@ -160,24 +170,53 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
160
170
|
assert_not_empty logged_excluding_reload_filter.last[:context]
|
161
171
|
assert_equal logged_excluding_reload_filter.last[:context], service_name: 'exception_handling'
|
162
172
|
end
|
173
|
+
|
174
|
+
should "log with Severity::WARN" do
|
175
|
+
ExceptionHandling.log_warning('This is a Warning', service_name: 'exception_handling')
|
176
|
+
assert_equal logged_excluding_reload_filter.last[:severity], 'WARN'
|
177
|
+
end
|
163
178
|
end
|
164
179
|
|
165
180
|
context "#log_info" do
|
166
181
|
should "take in additional key word args as logging context and pass them to the logger" do
|
167
|
-
ExceptionHandling.
|
182
|
+
ExceptionHandling.log_info('This is an Info', service_name: 'exception_handling')
|
168
183
|
assert_match(/This is an Info/, logged_excluding_reload_filter.last[:message])
|
169
184
|
assert_not_empty logged_excluding_reload_filter.last[:context]
|
170
185
|
assert_equal logged_excluding_reload_filter.last[:context], service_name: 'exception_handling'
|
171
186
|
end
|
187
|
+
|
188
|
+
should "log with Severity::INFO" do
|
189
|
+
ExceptionHandling.log_info('This is a Warning', service_name: 'exception_handling')
|
190
|
+
assert_equal logged_excluding_reload_filter.last[:severity], 'INFO'
|
191
|
+
end
|
172
192
|
end
|
173
193
|
|
174
194
|
context "#log_debug" do
|
175
195
|
should "take in additional key word args as logging context and pass them to the logger" do
|
176
|
-
ExceptionHandling.
|
196
|
+
ExceptionHandling.log_debug('This is a Debug', service_name: 'exception_handling')
|
177
197
|
assert_match(/This is a Debug/, logged_excluding_reload_filter.last[:message])
|
178
198
|
assert_not_empty logged_excluding_reload_filter.last[:context]
|
179
199
|
assert_equal logged_excluding_reload_filter.last[:context], service_name: 'exception_handling'
|
180
200
|
end
|
201
|
+
|
202
|
+
should "log with Severity::DEBUG" do
|
203
|
+
ExceptionHandling.log_debug('This is a Warning', service_name: 'exception_handling')
|
204
|
+
assert_equal logged_excluding_reload_filter.last[:severity], 'DEBUG'
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context "#write_exception_to_log" do
|
209
|
+
should "log warnings with Severity::WARN" do
|
210
|
+
warning = ExceptionHandling::Warning.new('This is a Warning')
|
211
|
+
ExceptionHandling.write_exception_to_log(warning, '', Time.now.to_i, service_name: 'exception_handling')
|
212
|
+
assert_equal logged_excluding_reload_filter.last[:severity], 'WARN'
|
213
|
+
end
|
214
|
+
|
215
|
+
should "log everything else with Severity::FATAL" do
|
216
|
+
error = RuntimeError.new('This is a runtime error')
|
217
|
+
ExceptionHandling.write_exception_to_log(error, '', Time.now.to_i, service_name: 'exception_handling')
|
218
|
+
assert_equal logged_excluding_reload_filter.last[:severity], 'FATAL'
|
219
|
+
end
|
181
220
|
end
|
182
221
|
|
183
222
|
context "configuration with custom_data_hook or post_log_error_hook" do
|
@@ -334,7 +373,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
334
373
|
|
335
374
|
if ActionView::VERSION::MAJOR >= 5
|
336
375
|
should "log an exception with call stack if an ActionView template exception is raised." do
|
337
|
-
mock(ExceptionHandling.logger).fatal(/\(Error:\d+\)
|
376
|
+
mock(ExceptionHandling.logger).fatal(/\(Error:\d+\) \nActionView::Template::Error: \(blah\):\n /, anything)
|
338
377
|
ExceptionHandling.ensure_safe do
|
339
378
|
begin
|
340
379
|
# Rails 5 made the switch from ActionView::TemplateError taking in the original exception
|
@@ -347,7 +386,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
347
386
|
end
|
348
387
|
else
|
349
388
|
should "log an exception with call stack if an ActionView template exception is raised." do
|
350
|
-
mock(ExceptionHandling.logger).fatal(/\(Error:\d+\)
|
389
|
+
mock(ExceptionHandling.logger).fatal(/\(Error:\d+\) \nActionView::Template::Error: \(blah\):\n /, anything)
|
351
390
|
ExceptionHandling.ensure_safe { raise ActionView::TemplateError.new({}, ArgumentError.new("blah")) }
|
352
391
|
end
|
353
392
|
end
|
@@ -370,7 +409,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
370
409
|
end
|
371
410
|
|
372
411
|
should "allow a message to be appended to the error when logged." do
|
373
|
-
mock(ExceptionHandling.logger).fatal(/mooo \(blah\):\n.*exception_handling_test\.rb/, anything)
|
412
|
+
mock(ExceptionHandling.logger).fatal(/mooo\nArgumentError: \(blah\):\n.*exception_handling_test\.rb/, anything)
|
374
413
|
b = ExceptionHandling.ensure_safe("mooo") { raise ArgumentError, "blah" }
|
375
414
|
assert_nil b
|
376
415
|
end
|
@@ -378,7 +417,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
378
417
|
should "only rescue StandardError and descendents" do
|
379
418
|
assert_raise(Exception) { ExceptionHandling.ensure_safe("mooo") { raise Exception } }
|
380
419
|
|
381
|
-
mock(ExceptionHandling.logger).fatal(/mooo \(blah\):\n.*exception_handling_test\.rb/, anything)
|
420
|
+
mock(ExceptionHandling.logger).fatal(/mooo\nStandardError: \(blah\):\n.*exception_handling_test\.rb/, anything)
|
382
421
|
|
383
422
|
b = ExceptionHandling.ensure_safe("mooo") { raise StandardError, "blah" }
|
384
423
|
assert_nil b
|
@@ -409,7 +448,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
409
448
|
end
|
410
449
|
|
411
450
|
should "allow a message to be appended to the error when logged." do
|
412
|
-
mock(ExceptionHandling.logger).fatal(/mooo \(blah\):\n.*exception_handling_test\.rb/, anything)
|
451
|
+
mock(ExceptionHandling.logger).fatal(/mooo\nArgumentError: \(blah\):\n.*exception_handling_test\.rb/, anything)
|
413
452
|
b = ExceptionHandling.ensure_completely_safe("mooo") { raise ArgumentError, "blah" }
|
414
453
|
assert_nil b
|
415
454
|
end
|
@@ -466,7 +505,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
466
505
|
ExceptionHandling.ensure_escalation("ensure context") { raise ArgumentError, "first_test_exception" }
|
467
506
|
|
468
507
|
assert_match(/ArgumentError.*first_test_exception/, log_fatals[0].first)
|
469
|
-
assert_match(/safe_email_deliver.*Delivery Error
|
508
|
+
assert_match(/safe_email_deliver.*Delivery Error/m, log_fatals[1].first)
|
470
509
|
|
471
510
|
assert_equal 2, log_fatals.size, log_fatals.inspect
|
472
511
|
|
@@ -536,7 +575,7 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
536
575
|
should "include the timestamp when the exception is logged" do
|
537
576
|
capture_notifications
|
538
577
|
|
539
|
-
mock(ExceptionHandling.logger).fatal(/\(Error:517033020\)
|
578
|
+
mock(ExceptionHandling.logger).fatal(/\(Error:517033020\) context\nArgumentError: \(blah\):\n.*exception_handling_test\.rb/, anything)
|
540
579
|
b = ExceptionHandling.ensure_safe("context") { raise ArgumentError, "blah" }
|
541
580
|
assert_nil b
|
542
581
|
|
@@ -616,68 +655,122 @@ class ExceptionHandlingTest < ActiveSupport::TestCase
|
|
616
655
|
ExceptionHandling.log_error(exception_with_nil_message)
|
617
656
|
end
|
618
657
|
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
honeybadger_data = nil
|
636
|
-
mock(Honeybadger).notify.with_any_args do |data|
|
637
|
-
honeybadger_data = data
|
658
|
+
context "with stubbed values" do
|
659
|
+
setup do
|
660
|
+
Time.now_override = Time.now
|
661
|
+
@env = { server: "fe98" }
|
662
|
+
@parameters = { advertiser_id: 435, controller: "some_controller" }
|
663
|
+
@session = { username: "jsmith" }
|
664
|
+
@request_uri = "host/path"
|
665
|
+
@controller = create_dummy_controller(@env, @parameters, @session, @request_uri)
|
666
|
+
stub(ExceptionHandling).server_name { "invoca_fe98" }
|
667
|
+
|
668
|
+
@exception = StandardError.new("Some Exception")
|
669
|
+
@exception.set_backtrace([
|
670
|
+
"test/unit/exception_handling_test.rb:847:in `exception_1'",
|
671
|
+
"test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
|
672
|
+
])
|
673
|
+
@exception_context = { "SERVER_NAME" => "exceptional.com" }
|
638
674
|
end
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
675
|
+
|
676
|
+
should "send error details and relevant context data to Honeybadger with log_context" do
|
677
|
+
honeybadger_data = nil
|
678
|
+
mock(Honeybadger).notify.with_any_args do |data|
|
679
|
+
honeybadger_data = data
|
680
|
+
end
|
681
|
+
ExceptionHandling.logger.global_context = { service_name: "rails", region: "AWS-us-east-1" }
|
682
|
+
log_context = { log_source: "gem/listen", service_name: "bin/console" }
|
683
|
+
ExceptionHandling.log_error(@exception, @exception_context, @controller, **log_context) do |data|
|
684
|
+
data[:scm_revision] = "5b24eac37aaa91f5784901e9aabcead36fd9df82"
|
685
|
+
data[:user_details] = { username: "jsmith" }
|
686
|
+
data[:event_response] = "Event successfully received"
|
687
|
+
data[:other_section] = "This should not be included in the response"
|
688
|
+
end
|
689
|
+
|
690
|
+
expected_data = {
|
691
|
+
error_class: :"Test Exception",
|
692
|
+
error_message: "Some Exception",
|
693
|
+
controller: "some_controller",
|
694
|
+
exception: @exception,
|
695
|
+
context: {
|
696
|
+
timestamp: Time.now.to_i,
|
697
|
+
error_class: "StandardError",
|
698
|
+
server: "invoca_fe98",
|
699
|
+
exception_context: { "SERVER_NAME" => "exceptional.com" },
|
700
|
+
scm_revision: "5b24eac37aaa91f5784901e9aabcead36fd9df82",
|
701
|
+
notes: "this is used by a test",
|
702
|
+
user_details: { "username" => "jsmith" },
|
703
|
+
request: {
|
704
|
+
"params" => { "advertiser_id" => 435, "controller" => "some_controller" },
|
705
|
+
"rails_root" => "Rails.root not defined. Is this a test environment?",
|
706
|
+
"url" => "host/path"
|
707
|
+
},
|
708
|
+
session: {
|
709
|
+
"key" => nil,
|
710
|
+
"data" => { "username" => "jsmith" }
|
711
|
+
},
|
712
|
+
environment: {
|
713
|
+
"SERVER_NAME" => "exceptional.com"
|
714
|
+
},
|
715
|
+
backtrace: [
|
716
|
+
"test/unit/exception_handling_test.rb:847:in `exception_1'",
|
717
|
+
"test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
|
718
|
+
],
|
719
|
+
event_response: "Event successfully received",
|
720
|
+
log_context: { "service_name" => "bin/console", "region" => "AWS-us-east-1", "log_source" => "gem/listen" }
|
721
|
+
}
|
722
|
+
}
|
723
|
+
assert_equal_with_diff expected_data, honeybadger_data
|
645
724
|
end
|
646
725
|
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
"SERVER_NAME" => "exceptional.com"
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
726
|
+
should "send error details and relevant context data to Honeybadger with empty log_context" do
|
727
|
+
honeybadger_data = nil
|
728
|
+
mock(Honeybadger).notify.with_any_args do |data|
|
729
|
+
honeybadger_data = data
|
730
|
+
end
|
731
|
+
ExceptionHandling.logger.global_context = {}
|
732
|
+
log_context = {}
|
733
|
+
ExceptionHandling.log_error(@exception, @exception_context, @controller, **log_context) do |data|
|
734
|
+
data[:scm_revision] = "5b24eac37aaa91f5784901e9aabcead36fd9df82"
|
735
|
+
data[:user_details] = { username: "jsmith" }
|
736
|
+
data[:event_response] = "Event successfully received"
|
737
|
+
data[:other_section] = "This should not be included in the response"
|
738
|
+
end
|
739
|
+
|
740
|
+
expected_data = {
|
741
|
+
error_class: :"Test Exception",
|
742
|
+
error_message: "Some Exception",
|
743
|
+
controller: "some_controller",
|
744
|
+
exception: @exception,
|
745
|
+
context: {
|
746
|
+
timestamp: Time.now.to_i,
|
747
|
+
error_class: "StandardError",
|
748
|
+
server: "invoca_fe98",
|
749
|
+
exception_context: { "SERVER_NAME" => "exceptional.com" },
|
750
|
+
scm_revision: "5b24eac37aaa91f5784901e9aabcead36fd9df82",
|
751
|
+
notes: "this is used by a test",
|
752
|
+
user_details: { "username" => "jsmith" },
|
753
|
+
request: {
|
754
|
+
"params" => { "advertiser_id" => 435, "controller" => "some_controller" },
|
755
|
+
"rails_root" => "Rails.root not defined. Is this a test environment?",
|
756
|
+
"url" => "host/path"
|
757
|
+
},
|
758
|
+
session: {
|
759
|
+
"key" => nil,
|
760
|
+
"data" => { "username" => "jsmith" }
|
761
|
+
},
|
762
|
+
environment: {
|
763
|
+
"SERVER_NAME" => "exceptional.com"
|
764
|
+
},
|
765
|
+
backtrace: [
|
766
|
+
"test/unit/exception_handling_test.rb:847:in `exception_1'",
|
767
|
+
"test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
|
768
|
+
],
|
769
|
+
event_response: "Event successfully received"
|
770
|
+
}
|
678
771
|
}
|
679
|
-
|
680
|
-
|
772
|
+
assert_equal_with_diff expected_data, honeybadger_data
|
773
|
+
end
|
681
774
|
end
|
682
775
|
|
683
776
|
context "with post_log_error_hook set" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_handling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.7.0.pre.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Invoca
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionmailer
|
@@ -143,6 +143,7 @@ files:
|
|
143
143
|
- lib/exception_handling/exception_info.rb
|
144
144
|
- lib/exception_handling/honeybadger_callbacks.rb
|
145
145
|
- lib/exception_handling/log_stub_error.rb
|
146
|
+
- lib/exception_handling/logging_methods.rb
|
146
147
|
- lib/exception_handling/mailer.rb
|
147
148
|
- lib/exception_handling/methods.rb
|
148
149
|
- lib/exception_handling/sensu.rb
|
@@ -150,12 +151,14 @@ files:
|
|
150
151
|
- lib/exception_handling/version.rb
|
151
152
|
- test/helpers/controller_helpers.rb
|
152
153
|
- test/helpers/exception_helpers.rb
|
154
|
+
- test/rake_test_warning_false.rb
|
153
155
|
- test/test_helper.rb
|
154
156
|
- test/unit/exception_handling/exception_catalog_test.rb
|
155
157
|
- test/unit/exception_handling/exception_description_test.rb
|
156
158
|
- test/unit/exception_handling/exception_info_test.rb
|
157
159
|
- test/unit/exception_handling/honeybadger_callbacks_test.rb
|
158
160
|
- test/unit/exception_handling/log_error_stub_test.rb
|
161
|
+
- test/unit/exception_handling/logging_methods_test.rb
|
159
162
|
- test/unit/exception_handling/mailer_test.rb
|
160
163
|
- test/unit/exception_handling/methods_test.rb
|
161
164
|
- test/unit/exception_handling/sensu_test.rb
|
@@ -191,12 +194,14 @@ summary: Invoca's exception handling logger/emailer layer, based on exception_no
|
|
191
194
|
test_files:
|
192
195
|
- test/helpers/controller_helpers.rb
|
193
196
|
- test/helpers/exception_helpers.rb
|
197
|
+
- test/rake_test_warning_false.rb
|
194
198
|
- test/test_helper.rb
|
195
199
|
- test/unit/exception_handling/exception_catalog_test.rb
|
196
200
|
- test/unit/exception_handling/exception_description_test.rb
|
197
201
|
- test/unit/exception_handling/exception_info_test.rb
|
198
202
|
- test/unit/exception_handling/honeybadger_callbacks_test.rb
|
199
203
|
- test/unit/exception_handling/log_error_stub_test.rb
|
204
|
+
- test/unit/exception_handling/logging_methods_test.rb
|
200
205
|
- test/unit/exception_handling/mailer_test.rb
|
201
206
|
- test/unit/exception_handling/methods_test.rb
|
202
207
|
- test/unit/exception_handling/sensu_test.rb
|