exception_handling 2.15.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: 14ca7f66e702ec2ae46aa9f7b7669cd8f8136b9305c0683b76339faafc87558a
4
- data.tar.gz: db7863d32347f5f859971222f2b215b0f84a8c7604eb0326cfd9b656910cd9ff
3
+ metadata.gz: 71ab070f1ab59f2f12838fb7d123fa541a71a8bb42fe0d057f06acb015bf32a2
4
+ data.tar.gz: 1c268f42c4a302c88b98411890db5a4870d31bb96ca712e0f6463ba6629f188a
5
5
  SHA512:
6
- metadata.gz: 3274bf4d7f67fb83aa2d71633572d19c14c99e3c40746de20e20efea1ff570a0d49f5163efd74c60ce0167af3495ad259d2950bc198c28a219ff6b30dadf551b
7
- data.tar.gz: 858ce36039ecfbd5a79a22c0a56f9accff534e7b7e27e288509ffd9d34feca3ccd0983a092f6d536e554dce8d4312cb877df5f3a6729305aed8828ed0fe36d8a
6
+ metadata.gz: f571e8c9dd62c70eba4b01c917af6c4715e3d4750900fec8ad7e4a3d5c67fc30ddc299c1456b48adef17c74a3860769806fd0df4e410cb5180c3f778e58c1aad
7
+ data.tar.gz: 98f1596f0a95e1591a768b23574c76e4b4039b54a7bb95f07b4f6d41d40336bae360b7ce76750cc5fec7d9c1a64c78ffc4c72d15b88b4924734bab228bb30c94
@@ -34,7 +34,7 @@ jobs:
34
34
  - uses: ruby/setup-ruby@v1
35
35
  with:
36
36
  ruby-version: ${{ matrix.ruby }}
37
- bundler: 2.2.29
37
+ bundler: 2.3.26
38
38
  bundler-cache: true
39
39
  - name: Unit tests
40
40
  run: bundle exec rspec
data/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@ 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.16.0] - 2023-05-01
8
+ ### Added
9
+ - Add interface for automatically adding honeybadger tags `ExceptionHandling.honeybadger_auto_tagger=`
10
+
7
11
  ## [2.15.0] - 2023-03-07
8
12
  ### Added
9
13
  - Added support for ActionMailer 7.x
@@ -109,6 +113,7 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
109
113
  ### Changed
110
114
  - No longer depends on hobo_support. Uses invoca-utils 0.3 instead.
111
115
 
116
+ [2.16.0]: https://github.com/Invoca/exception_handling/compare/v2.15.0...v2.16.0
112
117
  [2.15.0]: https://github.com/Invoca/exception_handling/compare/v2.14.0...v2.15.0
113
118
  [2.14.0]: https://github.com/Invoca/exception_handling/compare/v2.13.0...v2.14.0
114
119
  [2.13.0]: https://github.com/Invoca/exception_handling/compare/v2.12.0...v2.13.0
data/Gemfile CHANGED
@@ -4,6 +4,9 @@ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
+ gem 'actionmailer', '~> 6.0'
8
+ gem 'actionpack', '~> 6.0'
9
+ gem 'activesupport', '~> 6.0'
7
10
  gem 'appraisal', '~> 2.2'
8
11
  gem 'honeybadger', '~> 4.11'
9
12
  gem 'pry'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- exception_handling (2.15.0)
4
+ exception_handling (2.16.0)
5
5
  actionmailer (>= 5.2)
6
6
  actionpack (>= 5.2)
7
7
  activesupport (>= 5.2)
@@ -144,6 +144,9 @@ PLATFORMS
144
144
  ruby
145
145
 
146
146
  DEPENDENCIES
147
+ actionmailer (~> 6.0)
148
+ actionpack (~> 6.0)
149
+ activesupport (~> 6.0)
147
150
  appraisal (~> 2.2)
148
151
  exception_handling!
149
152
  honeybadger (~> 4.11)
@@ -156,4 +159,4 @@ DEPENDENCIES
156
159
  test-unit
157
160
 
158
161
  BUNDLED WITH
159
- 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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ExceptionHandling
4
- VERSION = '2.15.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.15.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-03-07 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
@@ -211,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
211
  - !ruby/object:Gem::Version
212
212
  version: '0'
213
213
  requirements: []
214
- rubygems_version: 3.4.7
214
+ rubygems_version: 3.1.6
215
215
  signing_key:
216
216
  specification_version: 4
217
217
  summary: Invoca's exception handling logger/emailer layer, based on exception_notifier.