exception_handling 2.14.0 → 2.16.0

Sign up to get free protection for your applications and to get access to all the features.
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