exception_handling 2.14.0 → 2.16.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0376880c57db8a6bc22e3f3c12aa587baacdbc89aa0a21d1d7ed325d785fa56d'
4
- data.tar.gz: 7eacb94e4c3cf1e08b7836bbe26595bcb61031f6ccf592bba55621fb82bdce7e
3
+ metadata.gz: 71ab070f1ab59f2f12838fb7d123fa541a71a8bb42fe0d057f06acb015bf32a2
4
+ data.tar.gz: 1c268f42c4a302c88b98411890db5a4870d31bb96ca712e0f6463ba6629f188a
5
5
  SHA512:
6
- metadata.gz: b409daeb7a13834e93badcfedb27dea72306f3ff25a97638b58724cf29f43c0010ad4ab1afef020603ce58ee965fe9c51aa44fcf21b9c22fd950799ce3c7b912
7
- data.tar.gz: 99a954e50c9e0902235e27437badec5b83c62f3161dd73b375b7b50259894c512b6e649fd200b3d2c69c0b91fd8cedac1891d4b09ecf82054e95c539a7010cbc
6
+ metadata.gz: f571e8c9dd62c70eba4b01c917af6c4715e3d4750900fec8ad7e4a3d5c67fc30ddc299c1456b48adef17c74a3860769806fd0df4e410cb5180c3f778e58c1aad
7
+ data.tar.gz: 98f1596f0a95e1591a768b23574c76e4b4039b54a7bb95f07b4f6d41d40336bae360b7ce76750cc5fec7d9c1a64c78ffc4c72d15b88b4924734bab228bb30c94
@@ -13,9 +13,16 @@ jobs:
13
13
  - Gemfile
14
14
  - gemfiles/rails_5.gemfile
15
15
  - gemfiles/rails_6.gemfile
16
+ - gemfiles/rails_7.gemfile
16
17
  exclude:
17
18
  - gemfile: Gemfile
18
19
  ruby: 2.5
20
+ - gemfile: gemfiles/rails_7.gemfile
21
+ ruby: 2.5
22
+ - gemfile: Gemfile
23
+ ruby: 2.6
24
+ - gemfile: gemfiles/rails_7.gemfile
25
+ ruby: 2.6
19
26
  - gemfile: gemfiles/rails_5.gemfile
20
27
  ruby: '3.0'
21
28
  - gemfile: gemfiles/rails_5.gemfile
@@ -27,7 +34,7 @@ jobs:
27
34
  - uses: ruby/setup-ruby@v1
28
35
  with:
29
36
  ruby-version: ${{ matrix.ruby }}
30
- bundler: 2.2.29
37
+ bundler: 2.3.26
31
38
  bundler-cache: true
32
39
  - name: Unit tests
33
40
  run: bundle exec rspec
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 2.7.5
data/Appraisals CHANGED
@@ -11,3 +11,9 @@ appraise "rails-6" do
11
11
  gem 'actionpack', '~> 6.0'
12
12
  gem 'activesupport', '~> 6.0'
13
13
  end
14
+
15
+ appraise "rails-7" do
16
+ gem 'actionmailer', '~> 7.0'
17
+ gem 'actionpack', '~> 7.0'
18
+ gem 'activesupport', '~> 7.0'
19
+ end
data/CHANGELOG.md CHANGED
@@ -2,7 +2,17 @@
2
2
 
3
3
  Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
- Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
+ **Note:** this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [2.16.0] - 2023-05-01
8
+ ### Added
9
+ - Add interface for automatically adding honeybadger tags `ExceptionHandling.honeybadger_auto_tagger=`
10
+
11
+ ## [2.15.0] - 2023-03-07
12
+ ### Added
13
+ - Added support for ActionMailer 7.x
14
+ - Added support for ActionPack 7.x
15
+ - Added support for ActiveSupport 7.x
6
16
 
7
17
  ## [2.14.0] - 2023-02-22
8
18
  ### Added
@@ -103,6 +113,8 @@ Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0
103
113
  ### Changed
104
114
  - No longer depends on hobo_support. Uses invoca-utils 0.3 instead.
105
115
 
116
+ [2.16.0]: https://github.com/Invoca/exception_handling/compare/v2.15.0...v2.16.0
117
+ [2.15.0]: https://github.com/Invoca/exception_handling/compare/v2.14.0...v2.15.0
106
118
  [2.14.0]: https://github.com/Invoca/exception_handling/compare/v2.13.0...v2.14.0
107
119
  [2.13.0]: https://github.com/Invoca/exception_handling/compare/v2.12.0...v2.13.0
108
120
  [2.12.0]: https://github.com/Invoca/exception_handling/compare/v2.11.3...v2.12.0
data/Gemfile CHANGED
@@ -2,15 +2,11 @@
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
-
10
5
  gemspec
11
6
 
12
- gem 'actionmailer', '< 6.1'
13
- gem 'activesupport', '< 6.1'
7
+ gem 'actionmailer', '~> 6.0'
8
+ gem 'actionpack', '~> 6.0'
9
+ gem 'activesupport', '~> 6.0'
14
10
  gem 'appraisal', '~> 2.2'
15
11
  gem 'honeybadger', '~> 4.11'
16
12
  gem 'pry'
data/Gemfile.lock CHANGED
@@ -1,10 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- exception_handling (2.14.0)
5
- actionmailer (>= 5.2, < 7.0)
6
- actionpack (>= 5.2, < 7.0)
7
- activesupport (>= 5.2, < 7.0)
4
+ exception_handling (2.16.0)
5
+ actionmailer (>= 5.2)
6
+ actionpack (>= 5.2)
7
+ activesupport (>= 5.2)
8
8
  contextual_logger (~> 1.0)
9
9
  escalate (~> 0.3)
10
10
  eventmachine (~> 1.0)
@@ -144,8 +144,9 @@ PLATFORMS
144
144
  ruby
145
145
 
146
146
  DEPENDENCIES
147
- actionmailer (< 6.1)
148
- activesupport (< 6.1)
147
+ actionmailer (~> 6.0)
148
+ actionpack (~> 6.0)
149
+ activesupport (~> 6.0)
149
150
  appraisal (~> 2.2)
150
151
  exception_handling!
151
152
  honeybadger (~> 4.11)
@@ -158,4 +159,4 @@ DEPENDENCIES
158
159
  test-unit
159
160
 
160
161
  BUNDLED WITH
161
- 2.2.29
162
+ 2.3.22
data/README.md CHANGED
@@ -25,24 +25,26 @@ Or install it yourself as:
25
25
  Add some code to initialize the settings in your application.
26
26
  For example:
27
27
 
28
- require "exception_handling"
29
-
30
- # required
31
- ExceptionHandling.server_name = Cluster['server_name']
32
- ExceptionHandling.sender_address = %("Exceptions" <exceptions@example.com>)
33
- ExceptionHandling.exception_recipients = ['exceptions@example.com']
34
- ExceptionHandling.logger = Rails.logger
35
-
36
- # optional
37
- ExceptionHandling.escalation_recipients = ['escalation@example.com']
38
- ExceptionHandling.filter_list_filename = "#{Rails.root}/config/exception_filters.yml"
39
- ExceptionHandling.email_environment = Rails.env
40
- ExceptionHandling.eventmachine_safe = false
41
- ExceptionHandling.eventmachine_synchrony = false
42
- ExceptionHandling.sensu_host = "127.0.0.1"
43
- ExceptionHandling.sensu_port = 3030
44
- ExceptionHandling.sensu_prefix = ""
45
-
28
+ ```ruby
29
+ require "exception_handling"
30
+
31
+ # required
32
+ ExceptionHandling.server_name = Cluster['server_name']
33
+ ExceptionHandling.sender_address = %("Exceptions" <exceptions@example.com>)
34
+ ExceptionHandling.exception_recipients = ['exceptions@example.com']
35
+ ExceptionHandling.logger = Rails.logger
36
+
37
+ # optional
38
+ ExceptionHandling.escalation_recipients = ['escalation@example.com']
39
+ ExceptionHandling.filter_list_filename = "#{Rails.root}/config/exception_filters.yml"
40
+ ExceptionHandling.email_environment = Rails.env
41
+ ExceptionHandling.eventmachine_safe = false
42
+ ExceptionHandling.eventmachine_synchrony = false
43
+ ExceptionHandling.sensu_host = "127.0.0.1"
44
+ ExceptionHandling.sensu_port = 3030
45
+ ExceptionHandling.sensu_prefix = ""
46
+ ExceptionHandling.honeybadger_auto_tagger = ->(exception) { [] } # See "Automatically Tagging Exceptions" section below for examples
47
+ ```
46
48
 
47
49
  ## Usage
48
50
 
@@ -62,6 +64,40 @@ Then call any method available in the `ExceptionHandling::Methods` mixin:
62
64
  flash.now['error'] = "A specific error occurred. Support has been notified."
63
65
  end
64
66
 
67
+ ### Tagging Exceptions in Honeybadger
68
+
69
+ ⚠️ Honeybadger differentiates tags by spaces and/or commas, so you should **not** include spaces or commas in your tags.
70
+
71
+ ⚠️ Tags are case-sensitive.
72
+
73
+ #### Manually Tagging Exceptions
74
+
75
+ Add `:honeybadger_tags` to your `log_context` usage with an array of strings.
76
+
77
+ ```ruby
78
+ log_error(ex, "A specific error occurred.", honeybadger_tags: ["critical", "sequoia"])
79
+ ```
80
+
81
+ **Note**: Manual tags will be merged with any automatic tags.
82
+
83
+ #### Automatically Tagging Exceptions (`honeybadger_auto_tagger=`)
84
+
85
+ Configure exception handling so that you can automatically apply multiple tags to exceptions sent to honeybadger.
86
+
87
+ The Proc must accept an `exception` argument that will be the exception in question and must always return an array of strings (the array can be empty).
88
+
89
+ Example to enable auto-tagging:
90
+ ```ruby
91
+ ExceptionHandling.honeybadger_auto_tagger = ->(exception) do
92
+ exception.message.match?(/fire/) ? ["high-urgency", "danger"] : ["low-urgency"]
93
+ end
94
+ ```
95
+
96
+ Example to disable auto-tagging:
97
+ ```ruby
98
+ ExceptionHandling.honeybadger_auto_tagger = nil
99
+ ```
100
+
65
101
  ## Custom Hooks
66
102
 
67
103
  ### custom_data_hook
@@ -20,9 +20,9 @@ Gem::Specification.new do |spec|
20
20
  "allowed_push_host" => "https://rubygems.org"
21
21
  }
22
22
 
23
- spec.add_dependency 'actionmailer', '>= 5.2', '< 7.0'
24
- spec.add_dependency 'actionpack', '>= 5.2', '< 7.0'
25
- spec.add_dependency 'activesupport', '>= 5.2', '< 7.0'
23
+ spec.add_dependency 'actionmailer', '>= 5.2'
24
+ spec.add_dependency 'actionpack', '>= 5.2'
25
+ spec.add_dependency 'activesupport', '>= 5.2'
26
26
  spec.add_dependency 'contextual_logger', '~> 1.0'
27
27
  spec.add_dependency 'escalate', '~> 0.3'
28
28
  spec.add_dependency 'eventmachine', '~> 1.0'
@@ -2,8 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "actionmailer", "~> 5.2"
6
- gem "activesupport", "~> 5.2"
7
5
  gem "appraisal", "~> 2.2"
8
6
  gem "honeybadger", "~> 4.11"
9
7
  gem "pry"
@@ -13,6 +11,8 @@ gem "rspec"
13
11
  gem "rspec_junit_formatter"
14
12
  gem "rubocop"
15
13
  gem "test-unit"
14
+ gem "actionmailer", "~> 5.2"
16
15
  gem "actionpack", "~> 5.2"
16
+ gem "activesupport", "~> 5.2"
17
17
 
18
18
  gemspec path: "../"
@@ -2,8 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "actionmailer", "~> 6.0"
6
- gem "activesupport", "~> 6.0"
7
5
  gem "appraisal", "~> 2.2"
8
6
  gem "honeybadger", "~> 4.11"
9
7
  gem "pry"
@@ -13,6 +11,8 @@ gem "rspec"
13
11
  gem "rspec_junit_formatter"
14
12
  gem "rubocop"
15
13
  gem "test-unit"
14
+ gem "actionmailer", "~> 6.0"
16
15
  gem "actionpack", "~> 6.0"
16
+ gem "activesupport", "~> 6.0"
17
17
 
18
18
  gemspec path: "../"
@@ -0,0 +1,18 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal", "~> 2.2"
6
+ gem "honeybadger", "~> 4.11"
7
+ gem "pry"
8
+ gem "pry-byebug"
9
+ gem "rake"
10
+ gem "rspec"
11
+ gem "rspec_junit_formatter"
12
+ gem "rubocop"
13
+ gem "test-unit"
14
+ gem "actionmailer", "~> 7.0"
15
+ gem "actionpack", "~> 7.0"
16
+ gem "activesupport", "~> 7.0"
17
+
18
+ gemspec path: "../"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ExceptionHandling
4
- VERSION = '2.14.0'
4
+ VERSION = '2.16.0'
5
5
  end
@@ -114,6 +114,7 @@ module ExceptionHandling # never included
114
114
  attr_reader :filter_list_filename
115
115
  attr_reader :eventmachine_safe
116
116
  attr_reader :eventmachine_synchrony
117
+ attr_reader :honeybadger_auto_tagger
117
118
 
118
119
  @filter_list_filename = "./config/exception_filters.yml"
119
120
  @email_environment = ""
@@ -154,6 +155,14 @@ module ExceptionHandling # never included
154
155
  @exception_catalog ||= ExceptionCatalog.new(@filter_list_filename)
155
156
  end
156
157
 
158
+ # rubocop:disable Style/TrivialAccessors
159
+ # @param value [Proc|nil] Proc that accepts 1 parameter that will be the exception object or nil to disable the auto-tagger.
160
+ # The proc is always expected to return an array of strings. The array can be empty.
161
+ def honeybadger_auto_tagger=(value)
162
+ @honeybadger_auto_tagger = value
163
+ end
164
+ # rubocop:enable Style/TrivialAccessors
165
+
157
166
  #
158
167
  # internal settings (don't set directly)
159
168
  #
@@ -270,9 +279,10 @@ module ExceptionHandling # never included
270
279
  def send_exception_to_honeybadger(exception_info)
271
280
  exception = exception_info.exception
272
281
  exception_description = exception_info.exception_description
282
+
273
283
  # Note: Both commas and spaces are treated as delimiters for the :tags string. Space-delimiters are not officially documented.
274
284
  # https://github.com/honeybadger-io/honeybadger-ruby/pull/422
275
- tags = exception_info.honeybadger_tags.join(' ')
285
+ tags = (honeybadger_auto_tags(exception) + exception_info.honeybadger_tags).join(' ')
276
286
  response = Honeybadger.notify(error_class: exception_description ? exception_description.filter_name : exception.class.name,
277
287
  error_message: exception.message.to_s,
278
288
  exception: exception,
@@ -286,6 +296,18 @@ module ExceptionHandling # never included
286
296
  :failure
287
297
  end
288
298
 
299
+ # @param exception [Exception]
300
+ #
301
+ # @return [Array<String>]
302
+ def honeybadger_auto_tags(exception)
303
+ @honeybadger_auto_tagger&.call(exception) || []
304
+ rescue => ex
305
+ traces = ex.backtrace.join("\n")
306
+ message = "Unable to execute honeybadger_auto_tags callback. #{ExceptionHandling.encode_utf8(ex.message.to_s)} #{traces}\n"
307
+ ExceptionHandling.log_info(message)
308
+ []
309
+ end
310
+
289
311
  #
290
312
  # Check if Honeybadger defined.
291
313
  #
@@ -107,6 +107,11 @@ describe ExceptionHandling do
107
107
  class SmtpClientErrbackStub < SmtpClientStub
108
108
  end
109
109
 
110
+ before(:each) do
111
+ # Reset this for every test since they are applied to the class
112
+ ExceptionHandling.honeybadger_auto_tagger = nil
113
+ end
114
+
110
115
  context "with warn and honeybadger notify stubbed" do
111
116
  before do
112
117
  allow(ExceptionHandling).to receive(:warn).with(any_args)
@@ -149,6 +154,14 @@ describe ExceptionHandling do
149
154
  expect(service_name: 'exception_handling').to eq(logged_excluding_reload_filter.last[:context])
150
155
  end
151
156
 
157
+ it "passes :honeybadger_tags in log context to honeybadger" do
158
+ expect(Honeybadger).to receive(:notify).with(hash_including({ tags: " , awesome , totallytubular, " }))
159
+ ExceptionHandling.log_error('This is an Error', 'This is the prefix context', honeybadger_tags: ' , awesome , totallytubular, ')
160
+
161
+ expect(Honeybadger).to receive(:notify).with(hash_including({ tags: " cool neat" }))
162
+ ExceptionHandling.log_error('This is an Error', 'This is the prefix context', honeybadger_tags: [" ", " cool ", "neat"])
163
+ end
164
+
152
165
  it "logs with Severity::FATAL" do
153
166
  ExceptionHandling.log_error('This is a Warning', service_name: 'exception_handling')
154
167
  expect('FATAL').to eq(logged_excluding_reload_filter.last[:severity])
@@ -1245,6 +1258,53 @@ describe ExceptionHandling do
1245
1258
  expect(logged_excluding_reload_filter.size).to eq(3)
1246
1259
  end
1247
1260
  end
1261
+
1262
+ context "#honeybadger_auto_tagger=" do
1263
+ context "with proc that runs successfully" do
1264
+ before do
1265
+ ExceptionHandling.honeybadger_auto_tagger =
1266
+ ->(exception) do
1267
+ if exception.message =~ /donuts/
1268
+ ['donut-error', 'high-urgency']
1269
+ else
1270
+ ['low-urgency']
1271
+ end
1272
+ end
1273
+ end
1274
+
1275
+ context "without manually passed tags" do
1276
+ let(:exception) { StandardError.new("We are out of chocolate milk") }
1277
+
1278
+ it "adds tags from autotagger" do
1279
+ expect(Honeybadger).to receive(:notify).with(hash_including({ tags: "low-urgency" }))
1280
+ ExceptionHandling.log_error(exception, nil)
1281
+ end
1282
+ end
1283
+
1284
+ context "with manually passed tags" do
1285
+ let(:exception) { StandardError.new("The donuts are burning") }
1286
+
1287
+ it "merges tags from autotagger with manually passed tags" do
1288
+ expect(Honeybadger).to receive(:notify).with(hash_including({ tags: "donut-error high-urgency upset-customers" }))
1289
+ ExceptionHandling.log_error(exception, nil, honeybadger_tags: ["upset-customers"])
1290
+ end
1291
+ end
1292
+ end
1293
+ end
1294
+
1295
+ context "with proc that raises an exception" do
1296
+ let(:exception) { StandardError.new("Something else occurred") }
1297
+
1298
+ before do
1299
+ ExceptionHandling.honeybadger_auto_tagger = ->(_exception) { raise StandardError, "boom" }
1300
+ end
1301
+
1302
+ it "logs a message and returns [] for the tags" do
1303
+ expect(Honeybadger).to receive(:notify).with(hash_including({ tags: "some-other-tag" }))
1304
+ expect(ExceptionHandling).to receive(:log_info).with(/Unable to execute honeybadger_auto_tags callback. boom/)
1305
+ ExceptionHandling.log_error(exception, nil, honeybadger_tags: ["some-other-tag"])
1306
+ end
1307
+ end
1248
1308
  end
1249
1309
 
1250
1310
  context "ExceptionHandling < 3.0 " 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.14.0
4
+ version: 2.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-22 00:00:00.000000000 Z
11
+ date: 2023-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionmailer
@@ -17,9 +17,6 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '5.2'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '7.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,9 +24,6 @@ dependencies:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '5.2'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '7.0'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: actionpack
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -37,9 +31,6 @@ dependencies:
37
31
  - - ">="
38
32
  - !ruby/object:Gem::Version
39
33
  version: '5.2'
40
- - - "<"
41
- - !ruby/object:Gem::Version
42
- version: '7.0'
43
34
  type: :runtime
44
35
  prerelease: false
45
36
  version_requirements: !ruby/object:Gem::Requirement
@@ -47,9 +38,6 @@ dependencies:
47
38
  - - ">="
48
39
  - !ruby/object:Gem::Version
49
40
  version: '5.2'
50
- - - "<"
51
- - !ruby/object:Gem::Version
52
- version: '7.0'
53
41
  - !ruby/object:Gem::Dependency
54
42
  name: activesupport
55
43
  requirement: !ruby/object:Gem::Requirement
@@ -57,9 +45,6 @@ dependencies:
57
45
  - - ">="
58
46
  - !ruby/object:Gem::Version
59
47
  version: '5.2'
60
- - - "<"
61
- - !ruby/object:Gem::Version
62
- version: '7.0'
63
48
  type: :runtime
64
49
  prerelease: false
65
50
  version_requirements: !ruby/object:Gem::Requirement
@@ -67,9 +52,6 @@ dependencies:
67
52
  - - ">="
68
53
  - !ruby/object:Gem::Version
69
54
  version: '5.2'
70
- - - "<"
71
- - !ruby/object:Gem::Version
72
- version: '7.0'
73
55
  - !ruby/object:Gem::Dependency
74
56
  name: contextual_logger
75
57
  requirement: !ruby/object:Gem::Requirement
@@ -167,6 +149,7 @@ files:
167
149
  - ".rspec"
168
150
  - ".rubocop.yml"
169
151
  - ".ruby-version"
152
+ - ".tool-versions"
170
153
  - Appraisals
171
154
  - CHANGELOG.md
172
155
  - Gemfile
@@ -178,6 +161,7 @@ files:
178
161
  - exception_handling.gemspec
179
162
  - gemfiles/rails_5.gemfile
180
163
  - gemfiles/rails_6.gemfile
164
+ - gemfiles/rails_7.gemfile
181
165
  - lib/exception_handling.rb
182
166
  - lib/exception_handling/escalate_callback.rb
183
167
  - lib/exception_handling/exception_catalog.rb