exception_handling 2.8.1 → 2.10.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/.github/workflows/pipeline.yml +27 -0
- data/CHANGELOG.md +15 -2
- data/Gemfile +8 -1
- data/Gemfile.lock +30 -30
- data/exception_handling.gemspec +1 -0
- data/gemfiles/rails_4.gemfile +3 -3
- data/gemfiles/rails_5.gemfile +3 -3
- data/gemfiles/rails_6.gemfile +3 -3
- data/lib/exception_handling/escalate_callback.rb +19 -0
- data/lib/exception_handling/version.rb +1 -1
- data/lib/exception_handling.rb +15 -8
- data/spec/unit/exception_handling/escalate_callback_spec.rb +81 -0
- data/spec/unit/exception_handling/mailer_spec.rb +0 -1
- data/spec/unit/exception_handling_spec.rb +15 -15
- metadata +22 -10
- data/.jenkins/Jenkinsfile +0 -113
- data/.jenkins/ruby_build_pod.yml +0 -18
- data/gemfiles/.bundle/config +0 -2
- data/lib/exception_handling/honeybadger_callbacks.rb +0 -59
- data/spec/unit/exception_handling/honeybadger_callbacks_spec.rb +0 -122
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5c1447aa42d931a3c1536f82ca2f9ed8131736d993eb663cbb1b48b14450839
|
4
|
+
data.tar.gz: b62e05ededb07b0b0eb9cb40187c5fb98ae1bf57c6a94577174be6161c011199
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bb9077980b89d4535e53447b18e0cdf7d188e497c48e1d51db30a22ad31474d6b006f64023e12003775d21633960a5a99420f48ffeea783a3c219976f3570c3
|
7
|
+
data.tar.gz: 4c0e1c5712b3250255808d49faf9c4af26e78cd218a45b720fae552edf104366d168deb4ce86732910e46082bf4539c3d42978a1fd07d49ab6bbb0045b1a1cc8
|
@@ -0,0 +1,27 @@
|
|
1
|
+
---
|
2
|
+
name: Pipeline
|
3
|
+
on: [push]
|
4
|
+
jobs:
|
5
|
+
tests:
|
6
|
+
name: Unit Tests
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby: [2.5, 2.6]
|
12
|
+
gemfile:
|
13
|
+
- Gemfile
|
14
|
+
- gemfiles/rails_4.gemfile
|
15
|
+
- gemfiles/rails_5.gemfile
|
16
|
+
- gemfiles/rails_6.gemfile
|
17
|
+
env:
|
18
|
+
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
19
|
+
steps:
|
20
|
+
- uses: actions/checkout@v2
|
21
|
+
- uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby }}
|
24
|
+
bundler: 1.17.3
|
25
|
+
bundler-cache: true
|
26
|
+
- name: Unit tests
|
27
|
+
run: bundle exec rspec
|
data/CHANGELOG.md
CHANGED
@@ -4,11 +4,23 @@ 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.10.0] - Unreleased
|
8
|
+
### Removed
|
9
|
+
- Remove custom object inspection
|
10
|
+
This removed Honeybadger-specific callbacks (`lib/exception_handling/honeybadger_callbacks.rb`)
|
11
|
+
|
12
|
+
### Deprecated
|
13
|
+
- Deprecated use of Honeybadger fork
|
14
|
+
|
15
|
+
## [2.9.0] - 2020-03-02
|
16
|
+
### Added
|
17
|
+
- Automatically registers with the `escalate` gem's `on_escalate` callback.
|
18
|
+
|
19
|
+
## [2.8.1] - 2020-12-01
|
8
20
|
### Added
|
9
21
|
- If the `log_context` key `honeybadger_grouping:` is set, pass that value to the `controller:` keyword argument of `HoneyBadger.notify`.
|
10
22
|
|
11
|
-
## [2.8.0] -
|
23
|
+
## [2.8.0] - 2020-10-19
|
12
24
|
### Deprecated
|
13
25
|
- Deprecated Email Escalation Methods: `escalate_to_production_support`, `escalate_error`, `escalate_warning`, `ensure_escalation`
|
14
26
|
|
@@ -60,6 +72,7 @@ Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0
|
|
60
72
|
### Changed
|
61
73
|
- No longer depends on hobo_support. Uses invoca-utils 0.3 instead.
|
62
74
|
|
75
|
+
[2.9.0]: https://github.com/Invoca/exception_handling/compare/v2.8.1...v2.9.0
|
63
76
|
[2.8.1]: https://github.com/Invoca/exception_handling/compare/v2.8.0...v2.8.1
|
64
77
|
[2.8.0]: https://github.com/Invoca/exception_handling/compare/v2.7.0...v2.8.0
|
65
78
|
[2.7.0]: https://github.com/Invoca/exception_handling/compare/v2.6.1...v2.7.0
|
data/Gemfile
CHANGED
@@ -2,10 +2,17 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
+
git_source(:github) do |repo_name|
|
6
|
+
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
|
7
|
+
"https://github.com/#{repo_name}.git"
|
8
|
+
end
|
9
|
+
|
5
10
|
gemspec
|
6
11
|
|
12
|
+
gem 'actionmailer', '< 6.1'
|
13
|
+
gem 'activesupport', '< 6.1'
|
7
14
|
gem 'appraisal', '~> 2.2'
|
8
|
-
gem 'honeybadger'
|
15
|
+
gem 'honeybadger'
|
9
16
|
gem 'pry'
|
10
17
|
gem 'pry-byebug'
|
11
18
|
gem 'rake'
|
data/Gemfile.lock
CHANGED
@@ -1,47 +1,41 @@
|
|
1
|
-
GIT
|
2
|
-
remote: git@github.com:Invoca/honeybadger-ruby
|
3
|
-
revision: bb5f2b8a86e4147c38a6270d39ad610fab4dd5e6
|
4
|
-
ref: bb5f2b8a86e4147c38a6270d39ad610fab4dd5e6
|
5
|
-
specs:
|
6
|
-
honeybadger (3.3.1.pre.1)
|
7
|
-
|
8
1
|
PATH
|
9
2
|
remote: .
|
10
3
|
specs:
|
11
|
-
exception_handling (2.
|
4
|
+
exception_handling (2.10.0.pre.1)
|
12
5
|
actionmailer (>= 4.2, < 7.0)
|
13
6
|
actionpack (>= 4.2, < 7.0)
|
14
7
|
activesupport (>= 4.2, < 7.0)
|
15
8
|
contextual_logger (~> 0.7)
|
9
|
+
escalate (~> 0.3)
|
16
10
|
eventmachine (~> 1.0)
|
17
11
|
invoca-utils (~> 0.3)
|
18
12
|
|
19
13
|
GEM
|
20
14
|
remote: https://rubygems.org/
|
21
15
|
specs:
|
22
|
-
actionmailer (6.0.3.
|
23
|
-
actionpack (= 6.0.3.
|
24
|
-
actionview (= 6.0.3.
|
25
|
-
activejob (= 6.0.3.
|
16
|
+
actionmailer (6.0.3.5)
|
17
|
+
actionpack (= 6.0.3.5)
|
18
|
+
actionview (= 6.0.3.5)
|
19
|
+
activejob (= 6.0.3.5)
|
26
20
|
mail (~> 2.5, >= 2.5.4)
|
27
21
|
rails-dom-testing (~> 2.0)
|
28
|
-
actionpack (6.0.3.
|
29
|
-
actionview (= 6.0.3.
|
30
|
-
activesupport (= 6.0.3.
|
22
|
+
actionpack (6.0.3.5)
|
23
|
+
actionview (= 6.0.3.5)
|
24
|
+
activesupport (= 6.0.3.5)
|
31
25
|
rack (~> 2.0, >= 2.0.8)
|
32
26
|
rack-test (>= 0.6.3)
|
33
27
|
rails-dom-testing (~> 2.0)
|
34
28
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
35
|
-
actionview (6.0.3.
|
36
|
-
activesupport (= 6.0.3.
|
29
|
+
actionview (6.0.3.5)
|
30
|
+
activesupport (= 6.0.3.5)
|
37
31
|
builder (~> 3.1)
|
38
32
|
erubi (~> 1.4)
|
39
33
|
rails-dom-testing (~> 2.0)
|
40
34
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
41
|
-
activejob (6.0.3.
|
42
|
-
activesupport (= 6.0.3.
|
35
|
+
activejob (6.0.3.5)
|
36
|
+
activesupport (= 6.0.3.5)
|
43
37
|
globalid (>= 0.3.6)
|
44
|
-
activesupport (6.0.3.
|
38
|
+
activesupport (6.0.3.5)
|
45
39
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
46
40
|
i18n (>= 0.7, < 2)
|
47
41
|
minitest (~> 5.1)
|
@@ -55,32 +49,35 @@ GEM
|
|
55
49
|
builder (3.2.4)
|
56
50
|
byebug (11.1.3)
|
57
51
|
coderay (1.1.2)
|
58
|
-
concurrent-ruby (1.1.
|
52
|
+
concurrent-ruby (1.1.8)
|
59
53
|
contextual_logger (0.11.0)
|
60
54
|
activesupport
|
61
55
|
json
|
62
56
|
crass (1.0.6)
|
63
57
|
diff-lcs (1.4.4)
|
64
58
|
erubi (1.10.0)
|
59
|
+
escalate (0.3.0)
|
65
60
|
eventmachine (1.2.7)
|
66
61
|
globalid (0.4.2)
|
67
62
|
activesupport (>= 4.2.0)
|
68
|
-
|
63
|
+
honeybadger (4.11.0)
|
64
|
+
i18n (1.8.9)
|
69
65
|
concurrent-ruby (~> 1.0)
|
70
66
|
invoca-utils (0.4.1)
|
71
67
|
jaro_winkler (1.5.3)
|
72
|
-
json (2.
|
73
|
-
loofah (2.
|
68
|
+
json (2.6.1)
|
69
|
+
loofah (2.9.0)
|
74
70
|
crass (~> 1.0.2)
|
75
71
|
nokogiri (>= 1.5.9)
|
76
72
|
mail (2.7.1)
|
77
73
|
mini_mime (>= 0.1.1)
|
78
74
|
method_source (0.9.2)
|
79
75
|
mini_mime (1.0.2)
|
80
|
-
mini_portile2 (2.
|
81
|
-
minitest (5.14.
|
82
|
-
nokogiri (1.
|
83
|
-
mini_portile2 (~> 2.
|
76
|
+
mini_portile2 (2.5.0)
|
77
|
+
minitest (5.14.4)
|
78
|
+
nokogiri (1.11.1)
|
79
|
+
mini_portile2 (~> 2.5.0)
|
80
|
+
racc (~> 1.4)
|
84
81
|
parallel (1.17.0)
|
85
82
|
parser (2.6.3.0)
|
86
83
|
ast (~> 2.4.0)
|
@@ -91,6 +88,7 @@ GEM
|
|
91
88
|
pry-byebug (3.8.0)
|
92
89
|
byebug (~> 11.0)
|
93
90
|
pry (~> 0.10)
|
91
|
+
racc (1.5.2)
|
94
92
|
rack (2.2.3)
|
95
93
|
rack-test (1.1.0)
|
96
94
|
rack (>= 1.0, < 3)
|
@@ -128,7 +126,7 @@ GEM
|
|
128
126
|
power_assert
|
129
127
|
thor (1.0.1)
|
130
128
|
thread_safe (0.3.6)
|
131
|
-
tzinfo (1.2.
|
129
|
+
tzinfo (1.2.9)
|
132
130
|
thread_safe (~> 0.1)
|
133
131
|
unicode-display_width (1.6.0)
|
134
132
|
zeitwerk (2.4.2)
|
@@ -137,9 +135,11 @@ PLATFORMS
|
|
137
135
|
ruby
|
138
136
|
|
139
137
|
DEPENDENCIES
|
138
|
+
actionmailer (< 6.1)
|
139
|
+
activesupport (< 6.1)
|
140
140
|
appraisal (~> 2.2)
|
141
141
|
exception_handling!
|
142
|
-
honeybadger
|
142
|
+
honeybadger
|
143
143
|
pry
|
144
144
|
pry-byebug
|
145
145
|
rake
|
data/exception_handling.gemspec
CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_dependency 'actionpack', '>= 4.2', '< 7.0'
|
25
25
|
spec.add_dependency 'activesupport', '>= 4.2', '< 7.0'
|
26
26
|
spec.add_dependency 'contextual_logger', '~> 0.7'
|
27
|
+
spec.add_dependency 'escalate', '~> 0.3'
|
27
28
|
spec.add_dependency 'eventmachine', '~> 1.0'
|
28
29
|
spec.add_dependency 'invoca-utils', '~> 0.3'
|
29
30
|
end
|
data/gemfiles/rails_4.gemfile
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
+
gem "actionmailer", "~> 4.2"
|
6
|
+
gem "activesupport", "~> 4.2"
|
5
7
|
gem "appraisal", "~> 2.2"
|
6
|
-
gem "honeybadger"
|
8
|
+
gem "honeybadger"
|
7
9
|
gem "pry"
|
8
10
|
gem "pry-byebug"
|
9
11
|
gem "rake"
|
@@ -11,8 +13,6 @@ gem "rspec"
|
|
11
13
|
gem "rspec_junit_formatter"
|
12
14
|
gem "rubocop"
|
13
15
|
gem "test-unit"
|
14
|
-
gem "actionmailer", "~> 4.2"
|
15
16
|
gem "actionpack", "~> 4.2"
|
16
|
-
gem "activesupport", "~> 4.2"
|
17
17
|
|
18
18
|
gemspec path: "../"
|
data/gemfiles/rails_5.gemfile
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
+
gem "actionmailer", "~> 5.2"
|
6
|
+
gem "activesupport", "~> 5.2"
|
5
7
|
gem "appraisal", "~> 2.2"
|
6
|
-
gem "honeybadger"
|
8
|
+
gem "honeybadger"
|
7
9
|
gem "pry"
|
8
10
|
gem "pry-byebug"
|
9
11
|
gem "rake"
|
@@ -11,8 +13,6 @@ gem "rspec"
|
|
11
13
|
gem "rspec_junit_formatter"
|
12
14
|
gem "rubocop"
|
13
15
|
gem "test-unit"
|
14
|
-
gem "actionmailer", "~> 5.2"
|
15
16
|
gem "actionpack", "~> 5.2"
|
16
|
-
gem "activesupport", "~> 5.2"
|
17
17
|
|
18
18
|
gemspec path: "../"
|
data/gemfiles/rails_6.gemfile
CHANGED
@@ -2,8 +2,10 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
+
gem "actionmailer", "~> 6.0"
|
6
|
+
gem "activesupport", "~> 6.0"
|
5
7
|
gem "appraisal", "~> 2.2"
|
6
|
-
gem "honeybadger"
|
8
|
+
gem "honeybadger"
|
7
9
|
gem "pry"
|
8
10
|
gem "pry-byebug"
|
9
11
|
gem "rake"
|
@@ -11,8 +13,6 @@ gem "rspec"
|
|
11
13
|
gem "rspec_junit_formatter"
|
12
14
|
gem "rubocop"
|
13
15
|
gem "test-unit"
|
14
|
-
gem "actionmailer", "~> 6.0"
|
15
16
|
gem "actionpack", "~> 6.0"
|
16
|
-
gem "activesupport", "~> 6.0"
|
17
17
|
|
18
18
|
gemspec path: "../"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'escalate'
|
4
|
+
|
5
|
+
module ExceptionHandling
|
6
|
+
module EscalateCallback
|
7
|
+
class << self
|
8
|
+
def register_if_configured!
|
9
|
+
register! if ::ExceptionHandling.configured?
|
10
|
+
end
|
11
|
+
|
12
|
+
def register!
|
13
|
+
Escalate.on_escalate(log_first: false) do |exception, location_message, **context|
|
14
|
+
::ExceptionHandling.log_error(exception, location_message, **context)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/exception_handling.rb
CHANGED
@@ -7,14 +7,14 @@ require 'contextual_logger'
|
|
7
7
|
|
8
8
|
require 'invoca/utils'
|
9
9
|
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
16
|
-
require
|
17
|
-
require
|
10
|
+
require 'exception_handling/mailer'
|
11
|
+
require 'exception_handling/sensu'
|
12
|
+
require 'exception_handling/methods'
|
13
|
+
require 'exception_handling/log_stub_error'
|
14
|
+
require 'exception_handling/exception_description'
|
15
|
+
require 'exception_handling/exception_catalog'
|
16
|
+
require 'exception_handling/exception_info'
|
17
|
+
require 'exception_handling/escalate_callback'
|
18
18
|
|
19
19
|
_ = ActiveSupport::HashWithIndifferentAccess
|
20
20
|
|
@@ -52,6 +52,10 @@ module ExceptionHandling # never included
|
|
52
52
|
@exception_recipients or raise ArgumentError, "You must assign a value to #{name}.exception_recipients"
|
53
53
|
end
|
54
54
|
|
55
|
+
def configured?
|
56
|
+
!@logger.nil?
|
57
|
+
end
|
58
|
+
|
55
59
|
def logger
|
56
60
|
@logger or raise ArgumentError, "You must assign a value to #{name}.logger"
|
57
61
|
end
|
@@ -63,6 +67,7 @@ module ExceptionHandling # never included
|
|
63
67
|
Deprecation3_0.deprecation_warning('implicit extend with ContextualLogger::LoggerMixin', 'extend your logger instance or include into your logger class first')
|
64
68
|
logger.extend(ContextualLogger::LoggerMixin)
|
65
69
|
end
|
70
|
+
EscalateCallback.register_if_configured!
|
66
71
|
end
|
67
72
|
|
68
73
|
def default_metric_name(exception_data, exception, treat_like_warning)
|
@@ -484,4 +489,6 @@ module ExceptionHandling # never included
|
|
484
489
|
end
|
485
490
|
end
|
486
491
|
end
|
492
|
+
|
493
|
+
EscalateCallback.register_if_configured!
|
487
494
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'exception_handling/escalate_callback'
|
4
|
+
require File.expand_path('../../spec_helper', __dir__)
|
5
|
+
|
6
|
+
module ExceptionHandling
|
7
|
+
describe EscalateCallback do
|
8
|
+
before do
|
9
|
+
class TestGem
|
10
|
+
class << self
|
11
|
+
attr_accessor :logger
|
12
|
+
end
|
13
|
+
include Escalate.mixin
|
14
|
+
end
|
15
|
+
TestGem.logger = logger
|
16
|
+
Escalate.clear_on_escalate_callbacks
|
17
|
+
end
|
18
|
+
|
19
|
+
after do
|
20
|
+
Escalate.clear_on_escalate_callbacks
|
21
|
+
end
|
22
|
+
|
23
|
+
let(:exception) do
|
24
|
+
raise "boom!"
|
25
|
+
rescue => ex
|
26
|
+
ex
|
27
|
+
end
|
28
|
+
let(:location_message) { "happened in TestGem" }
|
29
|
+
let(:context_hash) { { cuid: 'AABBCD' } }
|
30
|
+
let(:logger) { double("logger") }
|
31
|
+
|
32
|
+
describe '.register_if_configured!' do
|
33
|
+
context 'when already configured' do
|
34
|
+
before do
|
35
|
+
@original_logger = ExceptionHandling.logger
|
36
|
+
ExceptionHandling.logger = ::Logger.new('/dev/null')
|
37
|
+
end
|
38
|
+
|
39
|
+
after do
|
40
|
+
ExceptionHandling.logger = @original_logger
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'registers a callback' do
|
44
|
+
EscalateCallback.register_if_configured!
|
45
|
+
|
46
|
+
expect(logger).to_not receive(:error)
|
47
|
+
expect(logger).to_not receive(:fatal)
|
48
|
+
expect(ExceptionHandling).to receive(:log_error).with(exception, location_message, context_hash)
|
49
|
+
|
50
|
+
TestGem.escalate(exception, location_message, context: context_hash)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when not yet configured' do
|
55
|
+
before do
|
56
|
+
@original_logger = ExceptionHandling.logger
|
57
|
+
ExceptionHandling.logger = nil
|
58
|
+
end
|
59
|
+
|
60
|
+
after do
|
61
|
+
ExceptionHandling.logger = @original_logger
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'registers a callback once the logger is set' do
|
65
|
+
EscalateCallback.register_if_configured!
|
66
|
+
|
67
|
+
expect(Escalate.on_escalate_callbacks).to be_empty
|
68
|
+
|
69
|
+
ExceptionHandling.logger = ::Logger.new('/dev/null')
|
70
|
+
expect(Escalate.on_escalate_callbacks).to_not be_empty
|
71
|
+
|
72
|
+
expect(logger).to_not receive(:error)
|
73
|
+
expect(logger).to_not receive(:fatal)
|
74
|
+
expect(ExceptionHandling).to receive(:log_error).with(exception, location_message, context_hash)
|
75
|
+
|
76
|
+
TestGem.escalate(exception, location_message, context: context_hash)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -117,7 +117,7 @@ describe ExceptionHandling do
|
|
117
117
|
before { @original_logger = ExceptionHandling.logger }
|
118
118
|
after { ExceptionHandling.logger = @original_logger }
|
119
119
|
|
120
|
-
it "
|
120
|
+
it "stores logger as-is if it has ContextualLogger::Mixin" do
|
121
121
|
logger = Logger.new('/dev/null')
|
122
122
|
logger.extend(ContextualLogger::LoggerMixin)
|
123
123
|
ancestors = logger.singleton_class.ancestors.*.name
|
@@ -126,33 +126,33 @@ describe ExceptionHandling do
|
|
126
126
|
expect(ExceptionHandling.logger.singleton_class.ancestors.*.name).to eq(ancestors)
|
127
127
|
end
|
128
128
|
|
129
|
-
it "
|
129
|
+
it "allows logger = nil (no deprecation warning)" do
|
130
130
|
expect(STDERR).to receive(:puts).with(/DEPRECATION WARNING/).never
|
131
131
|
ExceptionHandling.logger = nil
|
132
132
|
end
|
133
133
|
|
134
|
-
it "[deprecated]
|
134
|
+
it "[deprecated] mixes in ContextualLogger::Mixin if not there" do
|
135
135
|
expect(STDERR).to receive(:puts).with(/DEPRECATION WARNING: implicit extend with ContextualLogger::LoggerMixin is deprecated and will be removed from exception_handling 3\.0/)
|
136
136
|
logger = Logger.new('/dev/null')
|
137
137
|
ancestors = logger.singleton_class.ancestors.*.name
|
138
138
|
|
139
139
|
ExceptionHandling.logger = logger
|
140
|
-
expect(ExceptionHandling.logger.singleton_class.ancestors.*.name).to_not eq(ancestors)
|
141
140
|
expect(ExceptionHandling.logger).to be_kind_of(ContextualLogger::LoggerMixin)
|
141
|
+
expect(ExceptionHandling.logger.singleton_class.ancestors.*.name).to_not eq(ancestors)
|
142
142
|
end
|
143
|
-
end
|
144
143
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
144
|
+
context "#log_error" do
|
145
|
+
it "takes in additional logging context hash and pass it to the logger" do
|
146
|
+
ExceptionHandling.log_error('This is an Error', 'This is the prefix context', service_name: 'exception_handling')
|
147
|
+
expect(logged_excluding_reload_filter.last[:message]).to match(/This is an Error/)
|
148
|
+
expect(logged_excluding_reload_filter.last[:context]).to_not be_empty
|
149
|
+
expect(service_name: 'exception_handling').to eq(logged_excluding_reload_filter.last[:context])
|
150
|
+
end
|
152
151
|
|
153
|
-
|
154
|
-
|
155
|
-
|
152
|
+
it "logs with Severity::FATAL" do
|
153
|
+
ExceptionHandling.log_error('This is a Warning', service_name: 'exception_handling')
|
154
|
+
expect('FATAL').to eq(logged_excluding_reload_filter.last[:severity])
|
155
|
+
end
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
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.10.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:
|
11
|
+
date: 2022-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionmailer
|
@@ -84,6 +84,20 @@ dependencies:
|
|
84
84
|
- - "~>"
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0.7'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: escalate
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0.3'
|
94
|
+
type: :runtime
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0.3'
|
87
101
|
- !ruby/object:Gem::Dependency
|
88
102
|
name: eventmachine
|
89
103
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,9 +133,8 @@ executables: []
|
|
119
133
|
extensions: []
|
120
134
|
extra_rdoc_files: []
|
121
135
|
files:
|
136
|
+
- ".github/workflows/pipeline.yml"
|
122
137
|
- ".gitignore"
|
123
|
-
- ".jenkins/Jenkinsfile"
|
124
|
-
- ".jenkins/ruby_build_pod.yml"
|
125
138
|
- ".rspec"
|
126
139
|
- ".rubocop.yml"
|
127
140
|
- ".ruby-version"
|
@@ -134,15 +147,14 @@ files:
|
|
134
147
|
- Rakefile
|
135
148
|
- config/exception_filters.yml
|
136
149
|
- exception_handling.gemspec
|
137
|
-
- gemfiles/.bundle/config
|
138
150
|
- gemfiles/rails_4.gemfile
|
139
151
|
- gemfiles/rails_5.gemfile
|
140
152
|
- gemfiles/rails_6.gemfile
|
141
153
|
- lib/exception_handling.rb
|
154
|
+
- lib/exception_handling/escalate_callback.rb
|
142
155
|
- lib/exception_handling/exception_catalog.rb
|
143
156
|
- lib/exception_handling/exception_description.rb
|
144
157
|
- lib/exception_handling/exception_info.rb
|
145
|
-
- lib/exception_handling/honeybadger_callbacks.rb
|
146
158
|
- lib/exception_handling/log_stub_error.rb
|
147
159
|
- lib/exception_handling/logging_methods.rb
|
148
160
|
- lib/exception_handling/mailer.rb
|
@@ -154,10 +166,10 @@ files:
|
|
154
166
|
- spec/helpers/exception_helpers.rb
|
155
167
|
- spec/rake_test_warning_false.rb
|
156
168
|
- spec/spec_helper.rb
|
169
|
+
- spec/unit/exception_handling/escalate_callback_spec.rb
|
157
170
|
- spec/unit/exception_handling/exception_catalog_spec.rb
|
158
171
|
- spec/unit/exception_handling/exception_description_spec.rb
|
159
172
|
- spec/unit/exception_handling/exception_info_spec.rb
|
160
|
-
- spec/unit/exception_handling/honeybadger_callbacks_spec.rb
|
161
173
|
- spec/unit/exception_handling/log_error_stub_spec.rb
|
162
174
|
- spec/unit/exception_handling/logging_methods_spec.rb
|
163
175
|
- spec/unit/exception_handling/mailer_spec.rb
|
@@ -183,9 +195,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
195
|
version: '0'
|
184
196
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
197
|
requirements:
|
186
|
-
- - "
|
198
|
+
- - ">"
|
187
199
|
- !ruby/object:Gem::Version
|
188
|
-
version:
|
200
|
+
version: 1.3.1
|
189
201
|
requirements: []
|
190
202
|
rubygems_version: 3.0.3
|
191
203
|
signing_key:
|
@@ -197,10 +209,10 @@ test_files:
|
|
197
209
|
- spec/helpers/exception_helpers.rb
|
198
210
|
- spec/rake_test_warning_false.rb
|
199
211
|
- spec/spec_helper.rb
|
212
|
+
- spec/unit/exception_handling/escalate_callback_spec.rb
|
200
213
|
- spec/unit/exception_handling/exception_catalog_spec.rb
|
201
214
|
- spec/unit/exception_handling/exception_description_spec.rb
|
202
215
|
- spec/unit/exception_handling/exception_info_spec.rb
|
203
|
-
- spec/unit/exception_handling/honeybadger_callbacks_spec.rb
|
204
216
|
- spec/unit/exception_handling/log_error_stub_spec.rb
|
205
217
|
- spec/unit/exception_handling/logging_methods_spec.rb
|
206
218
|
- spec/unit/exception_handling/mailer_spec.rb
|
data/.jenkins/Jenkinsfile
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
#!/usr/bin/groovy
|
2
|
-
@Library('jenkins-pipeline@v0.4.5')
|
3
|
-
import com.invoca.docker.*;
|
4
|
-
pipeline {
|
5
|
-
agent {
|
6
|
-
kubernetes {
|
7
|
-
defaultContainer "ruby"
|
8
|
-
yamlFile ".jenkins/ruby_build_pod.yml"
|
9
|
-
}
|
10
|
-
}
|
11
|
-
|
12
|
-
environment {
|
13
|
-
GITHUB_TOKEN = credentials('github_token')
|
14
|
-
GITHUB_KEY = credentials('github_key')
|
15
|
-
BUNDLE_GEM__FURY__IO = credentials('gemfury_deploy_token')
|
16
|
-
}
|
17
|
-
|
18
|
-
stages {
|
19
|
-
stage('Setup') {
|
20
|
-
steps {
|
21
|
-
script {
|
22
|
-
updateGitHubStatus('clean-build', 'pending', 'Unit tests.')
|
23
|
-
sh '''
|
24
|
-
# get SSH setup inside the container
|
25
|
-
eval `ssh-agent -s`
|
26
|
-
echo "$GITHUB_KEY" | ssh-add -
|
27
|
-
mkdir -p /root/.ssh
|
28
|
-
ssh-keyscan -t rsa github.com > /root/.ssh/known_hosts
|
29
|
-
|
30
|
-
bundle install
|
31
|
-
bundle exec appraisal install
|
32
|
-
'''
|
33
|
-
}
|
34
|
-
}
|
35
|
-
}
|
36
|
-
stage('Appraisals') {
|
37
|
-
parallel {
|
38
|
-
stage('Current') {
|
39
|
-
environment {
|
40
|
-
JUNIT_OUTPUT = 'spec/reports/current'
|
41
|
-
}
|
42
|
-
|
43
|
-
steps {
|
44
|
-
sh "bundle exec rspec --format RspecJunitFormatter --out ${JUNIT_OUTPUT}/rspec.xml"
|
45
|
-
}
|
46
|
-
|
47
|
-
post {
|
48
|
-
always { junit "${JUNIT_OUTPUT}/*.xml" }
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
stage('Rails 4') {
|
53
|
-
environment {
|
54
|
-
JUNIT_OUTPUT = 'spec/reports/rails-4'
|
55
|
-
}
|
56
|
-
|
57
|
-
steps {
|
58
|
-
sh "bundle exec appraisal rails-4 rspec --format RspecJunitFormatter --out ${JUNIT_OUTPUT}/rspec.xml"
|
59
|
-
}
|
60
|
-
|
61
|
-
post {
|
62
|
-
always { junit "${JUNIT_OUTPUT}/*.xml" }
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
|
-
stage('Rails 5') {
|
67
|
-
environment {
|
68
|
-
JUNIT_OUTPUT = 'spec/reports/rails-5'
|
69
|
-
}
|
70
|
-
|
71
|
-
steps {
|
72
|
-
sh "bundle exec appraisal rails-5 rspec --format RspecJunitFormatter --out ${JUNIT_OUTPUT}/rspec.xml"
|
73
|
-
}
|
74
|
-
|
75
|
-
post {
|
76
|
-
always { junit "${JUNIT_OUTPUT}/*.xml" }
|
77
|
-
}
|
78
|
-
}
|
79
|
-
|
80
|
-
stage('Rails 6') {
|
81
|
-
environment {
|
82
|
-
JUNIT_OUTPUT = 'spec/reports/rails-6'
|
83
|
-
}
|
84
|
-
|
85
|
-
steps {
|
86
|
-
sh "bundle exec appraisal rails-6 rspec --format RspecJunitFormatter --out ${JUNIT_OUTPUT}/rspec.xml"
|
87
|
-
}
|
88
|
-
|
89
|
-
post {
|
90
|
-
always { junit "${JUNIT_OUTPUT}/*.xml" }
|
91
|
-
}
|
92
|
-
}
|
93
|
-
}
|
94
|
-
|
95
|
-
post {
|
96
|
-
success { updateGitHubStatus('clean-build', 'success', 'Unit tests.') }
|
97
|
-
failure { updateGitHubStatus('clean-build', 'failure', 'Unit tests.') }
|
98
|
-
}
|
99
|
-
}
|
100
|
-
}
|
101
|
-
}
|
102
|
-
|
103
|
-
void updateGitHubStatus(String context, String status, String description) {
|
104
|
-
gitHubStatus([
|
105
|
-
repoSlug: 'Invoca/exception_handling',
|
106
|
-
sha: env.GIT_COMMIT,
|
107
|
-
description: description,
|
108
|
-
context: context,
|
109
|
-
targetURL: env.RUN_DISPLAY_URL,
|
110
|
-
token: env.GITHUB_TOKEN,
|
111
|
-
status: status
|
112
|
-
])
|
113
|
-
}
|
data/.jenkins/ruby_build_pod.yml
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
---
|
2
|
-
apiVersion: v1
|
3
|
-
kind: Pod
|
4
|
-
metadata:
|
5
|
-
labels:
|
6
|
-
jenkins/exception-handling: 'true'
|
7
|
-
namespace: jenkins
|
8
|
-
name: exception-handling
|
9
|
-
spec:
|
10
|
-
containers:
|
11
|
-
- name: ruby
|
12
|
-
image: ruby:2.6.5
|
13
|
-
tty: true
|
14
|
-
resources:
|
15
|
-
requests:
|
16
|
-
memory: "100Mi"
|
17
|
-
command:
|
18
|
-
- cat
|
data/gemfiles/.bundle/config
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ExceptionHandling
|
4
|
-
module HoneybadgerCallbacks
|
5
|
-
class << self
|
6
|
-
def register_callbacks
|
7
|
-
if ExceptionHandling.honeybadger_defined?
|
8
|
-
Honeybadger.local_variable_filter(&method(:local_variable_filter))
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def inspect_object(object, filter_keys)
|
15
|
-
inspection_output = object.inspect
|
16
|
-
|
17
|
-
if contains_filter_key?(filter_keys, inspection_output)
|
18
|
-
filtered_object(object)
|
19
|
-
else
|
20
|
-
inspection_output
|
21
|
-
end
|
22
|
-
rescue => ex
|
23
|
-
details = if object.respond_to?(:to_pk)
|
24
|
-
" @pk=#{object.to_pk}"
|
25
|
-
elsif object.respond_to?(:id)
|
26
|
-
" @id=#{object.id}"
|
27
|
-
end
|
28
|
-
|
29
|
-
"#<#{object.class.name}#{details} [error '#{ex.class.name}: #{ex.message}' while calling #inspect]>"
|
30
|
-
end
|
31
|
-
|
32
|
-
def local_variable_filter(_symbol, object, filter_keys)
|
33
|
-
case object
|
34
|
-
# Honeybadger will filter these data types for us
|
35
|
-
when String, Hash, Array, Set, Numeric, TrueClass, FalseClass, NilClass
|
36
|
-
object
|
37
|
-
else # handle other Ruby objects, intended for POROs
|
38
|
-
inspect_object(object, filter_keys)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def contains_filter_key?(filter_keys, string)
|
43
|
-
filter_keys&.any? { |key| string.include?(key) }
|
44
|
-
end
|
45
|
-
|
46
|
-
def filtered_object(object)
|
47
|
-
# make the output look similar to inspect
|
48
|
-
# use [FILTERED], just like honeybadger does
|
49
|
-
if object.respond_to?(:to_pk)
|
50
|
-
"#<#{object.class.name} @pk=#{object.to_pk}, [FILTERED]>"
|
51
|
-
elsif object.respond_to?(:id)
|
52
|
-
"#<#{object.class.name} @id=#{object.id}, [FILTERED]>"
|
53
|
-
else
|
54
|
-
"#<#{object.class.name} [FILTERED]>"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,122 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path('../../spec_helper', __dir__)
|
4
|
-
|
5
|
-
module ExceptionHandling
|
6
|
-
describe HoneybadgerCallbacks do
|
7
|
-
|
8
|
-
class TestPoroWithAttribute
|
9
|
-
attr_reader :test_attribute
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
@test_attribute = 'test'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class TestPoroWithFilteredAttribute
|
17
|
-
attr_reader :password
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
@password = 'secret'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
class TestPoroWithFilteredAttributeAndId < TestPoroWithFilteredAttribute
|
25
|
-
attr_reader :id
|
26
|
-
|
27
|
-
def initialize
|
28
|
-
super
|
29
|
-
@id = 1
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class TestPoroWithFilteredAttributePkAndId < TestPoroWithFilteredAttributeAndId
|
34
|
-
def to_pk
|
35
|
-
'TestPoroWithFilteredAttributePkAndId_1'
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
class TestRaiseOnInspect < TestPoroWithAttribute
|
40
|
-
def inspect
|
41
|
-
raise "some error"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class TestRaiseOnInspectWithId < TestRaiseOnInspect
|
46
|
-
def id
|
47
|
-
123
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
class TestRaiseOnInspectWithToPk < TestRaiseOnInspect
|
52
|
-
def to_pk
|
53
|
-
"SomeRecord-123"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context "register_callbacks" do
|
58
|
-
it "store the callbacks in the honeybadger object" do
|
59
|
-
HoneybadgerCallbacks.register_callbacks
|
60
|
-
result = Honeybadger.config.local_variable_filter.call(:variable_name, 'test', [])
|
61
|
-
expect(result).to eq('test')
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context "local_variable_filter" do
|
66
|
-
it "not inspect String, Hash, Array, Set, Numeric, TrueClass, FalseClass, NilClass" do
|
67
|
-
[
|
68
|
-
['test', String],
|
69
|
-
[{ a: 1 }, Hash],
|
70
|
-
[[1, 2], Array],
|
71
|
-
[Set.new([1, 2]), Set],
|
72
|
-
[4.5, Numeric],
|
73
|
-
[true, TrueClass],
|
74
|
-
[false, FalseClass],
|
75
|
-
[nil, NilClass]
|
76
|
-
].each do |object, expected_class|
|
77
|
-
result = HoneybadgerCallbacks.send(:local_variable_filter, :variable_name, object, [])
|
78
|
-
expect(result.is_a?(expected_class)).to be_truthy
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
it "inspect other classes" do
|
83
|
-
result = HoneybadgerCallbacks.send(:local_variable_filter, :variable_name, TestPoroWithAttribute.new, ['password'])
|
84
|
-
expect(result).to match(/#<ExceptionHandling::TestPoroWithAttribute:.* @test_attribute="test">/)
|
85
|
-
end
|
86
|
-
|
87
|
-
context "when inspect raises exceptions" do
|
88
|
-
it "handle exceptions for objects" do
|
89
|
-
result = HoneybadgerCallbacks.send(:local_variable_filter, :variable_name, TestRaiseOnInspect.new, ['password'])
|
90
|
-
expect(result).to eq("#<ExceptionHandling::TestRaiseOnInspect [error 'RuntimeError: some error' while calling #inspect]>")
|
91
|
-
end
|
92
|
-
|
93
|
-
it "handle exceptions for objects responding to id" do
|
94
|
-
result = HoneybadgerCallbacks.send(:local_variable_filter, :variable_name, TestRaiseOnInspectWithId.new, ['password'])
|
95
|
-
expect(result).to eq("#<ExceptionHandling::TestRaiseOnInspectWithId @id=123 [error 'RuntimeError: some error' while calling #inspect]>")
|
96
|
-
end
|
97
|
-
|
98
|
-
it "handle exceptions for objects responding to to_pk" do
|
99
|
-
result = HoneybadgerCallbacks.send(:local_variable_filter, :variable_name, TestRaiseOnInspectWithToPk.new, ['password'])
|
100
|
-
expect(result).to eq("#<ExceptionHandling::TestRaiseOnInspectWithToPk @pk=SomeRecord-123 [error 'RuntimeError: some error' while calling #inspect]>")
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
context "not inspect objects that contain filter keys" do
|
105
|
-
it "use to_pk if available, even if id is available" do
|
106
|
-
result = HoneybadgerCallbacks.send(:local_variable_filter, :variable_name, TestPoroWithFilteredAttributePkAndId.new, ['password'])
|
107
|
-
expect(result).to match(/#<ExceptionHandling::TestPoroWithFilteredAttributePkAndId @pk=TestPoroWithFilteredAttributePkAndId_1, \[FILTERED\]>/)
|
108
|
-
end
|
109
|
-
|
110
|
-
it "use id if to_pk is not available" do
|
111
|
-
result = HoneybadgerCallbacks.send(:local_variable_filter, :variable_name, TestPoroWithFilteredAttributeAndId.new, ['password'])
|
112
|
-
expect(result).to match(/#<ExceptionHandling::TestPoroWithFilteredAttributeAndId @id=1, \[FILTERED\]>/)
|
113
|
-
end
|
114
|
-
|
115
|
-
it "print the object name if no id or to_pk" do
|
116
|
-
result = HoneybadgerCallbacks.send(:local_variable_filter, :variable_name, TestPoroWithFilteredAttribute.new, ['password'])
|
117
|
-
expect(result).to match(/#<ExceptionHandling::TestPoroWithFilteredAttribute \[FILTERED\]>/)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|