exception_handling 3.1.2 → 3.2.0.pre.dc.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 +6 -25
- data/.gitignore +1 -0
- data/Appraisals +2 -15
- data/CHANGELOG.md +6 -0
- data/Gemfile +11 -1
- data/Gemfile.lock +28 -9
- data/README.md +26 -0
- data/catalog-info.yaml +39 -0
- data/gemfiles/rails_7_0.gemfile +10 -2
- data/gemfiles/rails_7_1.gemfile +10 -2
- data/gemfiles/rails_7_2.gemfile +25 -0
- data/gemfiles/rails_8_0.gemfile +25 -0
- data/lib/exception_handling/exception_description.rb +3 -1
- data/lib/exception_handling/exception_info.rb +8 -0
- data/lib/exception_handling/version.rb +1 -1
- data/lib/exception_handling.rb +70 -0
- data/spec/simplecov_helper.rb +23 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/exception_handling/exception_description_spec.rb +6 -0
- data/spec/unit/exception_handling/exception_info_spec.rb +42 -0
- data/spec/unit/exception_handling_spec.rb +188 -0
- metadata +8 -5
- data/gemfiles/rails_6_0.gemfile +0 -17
- data/gemfiles/rails_6_1.gemfile +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f292c98e64a5e880cc6a09979d1b9dbebd1fbe2a074f9d98a3a84391d6829107
|
|
4
|
+
data.tar.gz: b69dcabd0bada51da5ff4010c29a6aeb42e7a44f79841c5f7e14a55990a488fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9bc146dff9c619c77c3f9b17bac3b83bbb48787df2a07aa368a8fdee2ebd2d35260b903424abef82d91a3f5a75d44561cbb0812159ab27d9e4b5c7ff7dd5a493
|
|
7
|
+
data.tar.gz: e2ff09d2805cafc8d18993051c4ac568168a73a8de9eab1074de69de819b2e7025e7bd4eb6339f2a06b8ccfa4ab86c2f36f65e89052132f0b416924f8623c274
|
|
@@ -1,28 +1,9 @@
|
|
|
1
|
-
---
|
|
2
1
|
name: Pipeline
|
|
3
|
-
on:
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: '0 1 * * 1' # Every Monday at 1AM UTC
|
|
4
6
|
jobs:
|
|
5
7
|
tests:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
strategy:
|
|
9
|
-
fail-fast: false
|
|
10
|
-
matrix:
|
|
11
|
-
ruby: [2.7, '3.0', 3.1, 3.2, 3.3]
|
|
12
|
-
gemfile:
|
|
13
|
-
- Gemfile
|
|
14
|
-
- gemfiles/rails_6_0.gemfile
|
|
15
|
-
- gemfiles/rails_6_1.gemfile
|
|
16
|
-
- gemfiles/rails_7_0.gemfile
|
|
17
|
-
- gemfiles/rails_7_1.gemfile
|
|
18
|
-
env:
|
|
19
|
-
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
|
20
|
-
steps:
|
|
21
|
-
- uses: actions/checkout@v2
|
|
22
|
-
- uses: ruby/setup-ruby@v1
|
|
23
|
-
with:
|
|
24
|
-
ruby-version: ${{ matrix.ruby }}
|
|
25
|
-
bundler: 2.3.26
|
|
26
|
-
bundler-cache: true
|
|
27
|
-
- name: Unit tests
|
|
28
|
-
run: bundle exec rspec
|
|
8
|
+
uses: Invoca/ruby-test-matrix-workflow/.github/workflows/ruby-test-matrix.yml@main
|
|
9
|
+
secrets: inherit
|
data/.gitignore
CHANGED
data/Appraisals
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
appraise "rails-6-1" do
|
|
8
|
-
gem 'activesupport', '~> 6.1.0'
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
appraise "rails-7-0" do
|
|
12
|
-
gem 'activesupport', '~> 7.0.0'
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
appraise "rails-7-1" do
|
|
16
|
-
gem 'activesupport', '~> 7.1.0'
|
|
17
|
-
end
|
|
3
|
+
require "appraisal/matrix"
|
|
4
|
+
appraisal_matrix(rails: "7.0")
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ 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
|
+
## [3.2.0] - 2026-08-04
|
|
8
|
+
### Added
|
|
9
|
+
- Optional Sentry notifications from `send_external_notifications` via explicit `ExceptionHandling.enable_sentry` (requires `Sentry` to be defined and initialized)
|
|
10
|
+
- Sentry events include ExceptionHandling context, tags, controller name, and filter-based fingerprinting (aligned with Honeybadger grouping via `filter_name`)
|
|
11
|
+
- `send_to_sentry` exception filter flag (default `false`); filters with `send_to_honeybadger: true` also send to Sentry to ease migration
|
|
12
|
+
|
|
7
13
|
## [3.1.2] - 2024-05-08
|
|
8
14
|
### Fixed
|
|
9
15
|
- Fixed deprecation warnings that were coming from usage of `silence` when using this gem with Rails 7.1
|
data/Gemfile
CHANGED
|
@@ -5,7 +5,8 @@ source 'https://rubygems.org'
|
|
|
5
5
|
gemspec
|
|
6
6
|
|
|
7
7
|
gem 'activesupport'
|
|
8
|
-
gem 'appraisal'
|
|
8
|
+
gem 'appraisal'
|
|
9
|
+
gem 'appraisal-matrix'
|
|
9
10
|
gem 'gem-release'
|
|
10
11
|
gem 'honeybadger', '~> 4.11'
|
|
11
12
|
gem 'pry'
|
|
@@ -14,4 +15,13 @@ gem 'rake'
|
|
|
14
15
|
gem 'rspec'
|
|
15
16
|
gem 'rspec_junit_formatter'
|
|
16
17
|
gem 'rubocop'
|
|
18
|
+
gem 'simplecov', '~> 0.22'
|
|
19
|
+
gem 'simplecov-lcov', '~> 0.8'
|
|
17
20
|
gem 'test-unit'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
gem "concurrent-ruby", "~> 1.3", "< 1.3.5"
|
|
24
|
+
|
|
25
|
+
gem "base64", ">= 0.2.0"
|
|
26
|
+
gem "bigdecimal", ">= 3.1"
|
|
27
|
+
gem "mutex_m", ">= 0.2.0"
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
exception_handling (3.1
|
|
4
|
+
exception_handling (3.2.0.pre.dc.1)
|
|
5
5
|
activesupport (>= 5.2)
|
|
6
6
|
contextual_logger (~> 1.0)
|
|
7
7
|
escalate (~> 0.3)
|
|
@@ -25,25 +25,29 @@ GEM
|
|
|
25
25
|
bundler
|
|
26
26
|
rake
|
|
27
27
|
thor (>= 0.14.0)
|
|
28
|
+
appraisal-matrix (0.3.0)
|
|
29
|
+
appraisal (~> 2.2)
|
|
28
30
|
ast (2.4.2)
|
|
29
31
|
base64 (0.2.0)
|
|
30
32
|
bigdecimal (3.1.8)
|
|
31
33
|
byebug (11.1.3)
|
|
32
34
|
coderay (1.1.3)
|
|
33
|
-
concurrent-ruby (1.
|
|
35
|
+
concurrent-ruby (1.3.4)
|
|
34
36
|
connection_pool (2.4.1)
|
|
35
|
-
contextual_logger (1.
|
|
36
|
-
activesupport
|
|
37
|
+
contextual_logger (1.5.0)
|
|
38
|
+
activesupport (>= 6.0)
|
|
37
39
|
json
|
|
40
|
+
date (3.5.1)
|
|
38
41
|
diff-lcs (1.5.1)
|
|
42
|
+
docile (1.4.1)
|
|
39
43
|
drb (2.2.1)
|
|
40
44
|
escalate (0.3.0)
|
|
41
45
|
gem-release (2.2.2)
|
|
42
46
|
honeybadger (4.12.2)
|
|
43
47
|
i18n (1.14.5)
|
|
44
48
|
concurrent-ruby (~> 1.0)
|
|
45
|
-
invoca-utils (0.
|
|
46
|
-
activesupport (>=
|
|
49
|
+
invoca-utils (0.7.0)
|
|
50
|
+
activesupport (>= 6.0)
|
|
47
51
|
json (2.7.2)
|
|
48
52
|
language_server-protocol (3.17.0.3)
|
|
49
53
|
method_source (1.1.0)
|
|
@@ -60,7 +64,8 @@ GEM
|
|
|
60
64
|
pry-byebug (3.10.1)
|
|
61
65
|
byebug (~> 11.0)
|
|
62
66
|
pry (>= 0.13, < 0.15)
|
|
63
|
-
psych (5.
|
|
67
|
+
psych (5.4.0)
|
|
68
|
+
date
|
|
64
69
|
stringio
|
|
65
70
|
racc (1.7.3)
|
|
66
71
|
rainbow (3.1.1)
|
|
@@ -96,7 +101,14 @@ GEM
|
|
|
96
101
|
rubocop-ast (1.31.3)
|
|
97
102
|
parser (>= 3.3.1.0)
|
|
98
103
|
ruby-progressbar (1.13.0)
|
|
99
|
-
|
|
104
|
+
simplecov (0.22.0)
|
|
105
|
+
docile (~> 1.1)
|
|
106
|
+
simplecov-html (~> 0.11)
|
|
107
|
+
simplecov_json_formatter (~> 0.1)
|
|
108
|
+
simplecov-html (0.13.2)
|
|
109
|
+
simplecov-lcov (0.9.0)
|
|
110
|
+
simplecov_json_formatter (0.1.4)
|
|
111
|
+
stringio (3.2.0)
|
|
100
112
|
test-unit (3.6.2)
|
|
101
113
|
power_assert
|
|
102
114
|
thor (1.3.1)
|
|
@@ -109,16 +121,23 @@ PLATFORMS
|
|
|
109
121
|
|
|
110
122
|
DEPENDENCIES
|
|
111
123
|
activesupport
|
|
112
|
-
appraisal
|
|
124
|
+
appraisal
|
|
125
|
+
appraisal-matrix
|
|
126
|
+
base64 (>= 0.2.0)
|
|
127
|
+
bigdecimal (>= 3.1)
|
|
128
|
+
concurrent-ruby (~> 1.3, < 1.3.5)
|
|
113
129
|
exception_handling!
|
|
114
130
|
gem-release
|
|
115
131
|
honeybadger (~> 4.11)
|
|
132
|
+
mutex_m (>= 0.2.0)
|
|
116
133
|
pry
|
|
117
134
|
pry-byebug
|
|
118
135
|
rake
|
|
119
136
|
rspec
|
|
120
137
|
rspec_junit_formatter
|
|
121
138
|
rubocop
|
|
139
|
+
simplecov (~> 0.22)
|
|
140
|
+
simplecov-lcov (~> 0.8)
|
|
122
141
|
test-unit
|
|
123
142
|
|
|
124
143
|
BUNDLED WITH
|
data/README.md
CHANGED
|
@@ -39,6 +39,32 @@ ExceptionHandling.honeybadger_auto_tagger = ->(exception) { [] } # See "Automati
|
|
|
39
39
|
ExceptionHandling.add_honeybadger_tag_from_log_context("tag-name", path: ["path", "in", "log", "context"])
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
### External error trackers (Honeybadger / Sentry)
|
|
43
|
+
|
|
44
|
+
ExceptionHandling notifies configured external services from `log_error` (and related paths):
|
|
45
|
+
|
|
46
|
+
- **Honeybadger** — when the `Honeybadger` constant is defined
|
|
47
|
+
- **Sentry** — only after you call `ExceptionHandling.enable_sentry` (requires `Sentry` to be defined and initialized)
|
|
48
|
+
|
|
49
|
+
Both can run at the same time. This gem does not depend on `sentry-ruby`; initialize Sentry in the host application, then opt in:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
Sentry.init do |config|
|
|
53
|
+
config.dsn = ENV["SENTRY_DSN"]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
ExceptionHandling.enable_sentry
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When enabled, ExceptionHandling sends the same contextual sections it builds for Honeybadger (request/session/environment/log context, etc.), maps tags into Sentry tag key/values, sets controller context when present, and fingerprints matched filters by `filter_name` so grouping stays aligned across services.
|
|
60
|
+
|
|
61
|
+
Matched exception filters in `exception_filters.yml` control delivery:
|
|
62
|
+
|
|
63
|
+
- `send_to_honeybadger: true` — send to Honeybadger (and also to Sentry during migration, when Sentry is enabled)
|
|
64
|
+
- `send_to_sentry: true` — send to Sentry (when Sentry is enabled)
|
|
65
|
+
- Unmatched exceptions are sent when the corresponding service is active
|
|
66
|
+
- Matched filters with both flags false skip both services
|
|
67
|
+
|
|
42
68
|
## Usage
|
|
43
69
|
|
|
44
70
|
Mixin the `ExceptionHandling::Methods` module into your controllers, models or classes. The example below adds it to all the controllers in you rails application:
|
data/catalog-info.yaml
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# This file is partially auto-generated by the invoca-backstage-tools gem
|
|
2
|
+
# The following fields should not be edited manually as they are auto-generated
|
|
3
|
+
# based on the contents of the repo:
|
|
4
|
+
# - metadata.name
|
|
5
|
+
# - metadata.title
|
|
6
|
+
# - metadata.description
|
|
7
|
+
# - annotations.github.com/project-slug
|
|
8
|
+
# - invoca.com/version-repository-location
|
|
9
|
+
# - invoca.com/version-repository-name
|
|
10
|
+
# - spec.type
|
|
11
|
+
# - spec.owner
|
|
12
|
+
---
|
|
13
|
+
apiVersion: backstage.io/v1alpha1
|
|
14
|
+
kind: Component
|
|
15
|
+
metadata:
|
|
16
|
+
name: exception_handling-gem
|
|
17
|
+
title: ExceptionHandling
|
|
18
|
+
annotations:
|
|
19
|
+
buildkite.com/project-slug: Invoca/exception_handling
|
|
20
|
+
github.com/project-slug: Invoca/exception_handling
|
|
21
|
+
invoca.com/version-repository-location: rubygems
|
|
22
|
+
invoca.com/version-repository-name: exception_handling
|
|
23
|
+
endoflife.date/products: ruby@3.3
|
|
24
|
+
tags:
|
|
25
|
+
- ruby
|
|
26
|
+
- open-source
|
|
27
|
+
- gem
|
|
28
|
+
- public
|
|
29
|
+
- rails-dependent
|
|
30
|
+
description: Exception handling logger
|
|
31
|
+
spec:
|
|
32
|
+
type: library
|
|
33
|
+
lifecycle: production
|
|
34
|
+
owner: octothorpe
|
|
35
|
+
system: platform-observability
|
|
36
|
+
dependsOn:
|
|
37
|
+
- component:escalate-gem
|
|
38
|
+
- component:invoca-utils-gem
|
|
39
|
+
- component:contextual_logger-gem
|
data/gemfiles/rails_7_0.gemfile
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
source "https://rubygems.org"
|
|
4
4
|
|
|
5
|
-
gem "activesupport"
|
|
6
|
-
gem "appraisal"
|
|
5
|
+
gem "activesupport"
|
|
6
|
+
gem "appraisal"
|
|
7
|
+
gem "appraisal-matrix"
|
|
7
8
|
gem "gem-release"
|
|
8
9
|
gem "honeybadger", "~> 4.11"
|
|
9
10
|
gem "pry"
|
|
@@ -13,5 +14,12 @@ gem "rspec"
|
|
|
13
14
|
gem "rspec_junit_formatter"
|
|
14
15
|
gem "rubocop"
|
|
15
16
|
gem "test-unit"
|
|
17
|
+
gem "concurrent-ruby", "~> 1.3", "< 1.3.5"
|
|
18
|
+
gem "base64", ">= 0.2.0"
|
|
19
|
+
gem "bigdecimal", ">= 3.1"
|
|
20
|
+
gem "mutex_m", ">= 0.2.0"
|
|
21
|
+
gem "rails", "~> 7.0.0"
|
|
22
|
+
gem "simplecov", "~> 0.22"
|
|
23
|
+
gem "simplecov-lcov", "~> 0.8"
|
|
16
24
|
|
|
17
25
|
gemspec path: "../"
|
data/gemfiles/rails_7_1.gemfile
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
source "https://rubygems.org"
|
|
4
4
|
|
|
5
|
-
gem "activesupport"
|
|
6
|
-
gem "appraisal"
|
|
5
|
+
gem "activesupport"
|
|
6
|
+
gem "appraisal"
|
|
7
|
+
gem "appraisal-matrix"
|
|
7
8
|
gem "gem-release"
|
|
8
9
|
gem "honeybadger", "~> 4.11"
|
|
9
10
|
gem "pry"
|
|
@@ -13,5 +14,12 @@ gem "rspec"
|
|
|
13
14
|
gem "rspec_junit_formatter"
|
|
14
15
|
gem "rubocop"
|
|
15
16
|
gem "test-unit"
|
|
17
|
+
gem "concurrent-ruby", "~> 1.3", "< 1.3.5"
|
|
18
|
+
gem "base64", ">= 0.2.0"
|
|
19
|
+
gem "bigdecimal", ">= 3.1"
|
|
20
|
+
gem "mutex_m", ">= 0.2.0"
|
|
21
|
+
gem "rails", "~> 7.1.0"
|
|
22
|
+
gem "simplecov", "~> 0.22"
|
|
23
|
+
gem "simplecov-lcov", "~> 0.8"
|
|
16
24
|
|
|
17
25
|
gemspec path: "../"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "activesupport"
|
|
6
|
+
gem "appraisal"
|
|
7
|
+
gem "appraisal-matrix"
|
|
8
|
+
gem "gem-release"
|
|
9
|
+
gem "honeybadger", "~> 4.11"
|
|
10
|
+
gem "pry"
|
|
11
|
+
gem "pry-byebug"
|
|
12
|
+
gem "rake"
|
|
13
|
+
gem "rspec"
|
|
14
|
+
gem "rspec_junit_formatter"
|
|
15
|
+
gem "rubocop"
|
|
16
|
+
gem "test-unit"
|
|
17
|
+
gem "concurrent-ruby", "~> 1.3", "< 1.3.5"
|
|
18
|
+
gem "base64", ">= 0.2.0"
|
|
19
|
+
gem "bigdecimal", ">= 3.1"
|
|
20
|
+
gem "mutex_m", ">= 0.2.0"
|
|
21
|
+
gem "rails", "~> 7.2.0"
|
|
22
|
+
gem "simplecov", "~> 0.22"
|
|
23
|
+
gem "simplecov-lcov", "~> 0.8"
|
|
24
|
+
|
|
25
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "activesupport"
|
|
6
|
+
gem "appraisal"
|
|
7
|
+
gem "appraisal-matrix"
|
|
8
|
+
gem "gem-release"
|
|
9
|
+
gem "honeybadger", "~> 4.11"
|
|
10
|
+
gem "pry"
|
|
11
|
+
gem "pry-byebug"
|
|
12
|
+
gem "rake"
|
|
13
|
+
gem "rspec"
|
|
14
|
+
gem "rspec_junit_formatter"
|
|
15
|
+
gem "rubocop"
|
|
16
|
+
gem "test-unit"
|
|
17
|
+
gem "concurrent-ruby", "~> 1.3", "< 1.3.5"
|
|
18
|
+
gem "base64", ">= 0.2.0"
|
|
19
|
+
gem "bigdecimal", ">= 3.1"
|
|
20
|
+
gem "mutex_m", ">= 0.2.0"
|
|
21
|
+
gem "rails", "~> 8.0.0"
|
|
22
|
+
gem "simplecov", "~> 0.22"
|
|
23
|
+
gem "simplecov-lcov", "~> 0.8"
|
|
24
|
+
|
|
25
|
+
gemspec path: "../"
|
|
@@ -6,12 +6,13 @@ module ExceptionHandling
|
|
|
6
6
|
|
|
7
7
|
CONFIGURATION_SECTIONS = {
|
|
8
8
|
send_to_honeybadger: false, # should be sent to honeybadger?
|
|
9
|
+
send_to_sentry: false, # should be sent to sentry?
|
|
9
10
|
send_metric: true, # should the metric be sent.
|
|
10
11
|
metric_name: nil, # Will be derived from section name if not passed
|
|
11
12
|
notes: nil # Will be included in exception email if set, used to keep notes and relevant links
|
|
12
13
|
}.freeze
|
|
13
14
|
|
|
14
|
-
attr_reader :filter_name, :send_to_honeybadger, :send_metric, :metric_name, :notes
|
|
15
|
+
attr_reader :filter_name, :send_to_honeybadger, :send_to_sentry, :send_metric, :metric_name, :notes
|
|
15
16
|
|
|
16
17
|
def initialize(filter_name, configuration)
|
|
17
18
|
@filter_name = filter_name
|
|
@@ -21,6 +22,7 @@ module ExceptionHandling
|
|
|
21
22
|
|
|
22
23
|
@configuration = CONFIGURATION_SECTIONS.merge(configuration)
|
|
23
24
|
@send_to_honeybadger = @configuration[:send_to_honeybadger]
|
|
25
|
+
@send_to_sentry = @configuration[:send_to_sentry]
|
|
24
26
|
@send_metric = @configuration[:send_metric]
|
|
25
27
|
@metric_name = (@configuration[:metric_name] || @filter_name).to_s.gsub(" ", "_")
|
|
26
28
|
@notes = @configuration[:notes]
|
|
@@ -78,6 +78,14 @@ module ExceptionHandling
|
|
|
78
78
|
ExceptionHandling.honeybadger_defined? && (!exception_description || exception_description.send_to_honeybadger)
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
+
def send_to_sentry?
|
|
82
|
+
ExceptionHandling.sentry_enabled? && (
|
|
83
|
+
!exception_description ||
|
|
84
|
+
exception_description.send_to_sentry ||
|
|
85
|
+
exception_description.send_to_honeybadger
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
|
|
81
89
|
def honeybadger_context_data
|
|
82
90
|
@honeybadger_context_data ||= enhanced_data_to_honeybadger_context
|
|
83
91
|
end
|
data/lib/exception_handling.rb
CHANGED
|
@@ -211,6 +211,9 @@ module ExceptionHandling # never included
|
|
|
211
211
|
if honeybadger_defined?
|
|
212
212
|
results[:honeybadger_status] = send_exception_to_honeybadger_unless_filtered(exception_info)
|
|
213
213
|
end
|
|
214
|
+
if sentry_enabled?
|
|
215
|
+
results[:sentry_status] = send_exception_to_sentry_unless_filtered(exception_info)
|
|
216
|
+
end
|
|
214
217
|
results
|
|
215
218
|
end
|
|
216
219
|
|
|
@@ -249,6 +252,39 @@ module ExceptionHandling # never included
|
|
|
249
252
|
:failure
|
|
250
253
|
end
|
|
251
254
|
|
|
255
|
+
# Returns :success or :failure or :skipped
|
|
256
|
+
def send_exception_to_sentry_unless_filtered(exception_info)
|
|
257
|
+
if exception_info.send_to_sentry?
|
|
258
|
+
send_exception_to_sentry(exception_info)
|
|
259
|
+
else
|
|
260
|
+
log_info("Filtered exception using '#{exception_info.exception_description.filter_name}'; not sending notification to Sentry")
|
|
261
|
+
:skipped
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
#
|
|
266
|
+
# Log exception to Sentry.
|
|
267
|
+
#
|
|
268
|
+
# Returns :success or :failure
|
|
269
|
+
#
|
|
270
|
+
def send_exception_to_sentry(exception_info)
|
|
271
|
+
exception = exception_info.exception
|
|
272
|
+
exception_description = exception_info.exception_description
|
|
273
|
+
|
|
274
|
+
response = Sentry.capture_exception(exception) do |scope|
|
|
275
|
+
tags = tags_hash_for_sentry(exception_info)
|
|
276
|
+
scope.set_tags(tags) if tags.any?
|
|
277
|
+
scope.set_context("exception_handling", exception_info.honeybadger_context_data)
|
|
278
|
+
scope.set_context("controller", { name: exception_info.controller_name }) if exception_info.controller_name.present?
|
|
279
|
+
scope.set_fingerprint([exception_description.filter_name.to_s]) if exception_description
|
|
280
|
+
end
|
|
281
|
+
response ? :success : :failure
|
|
282
|
+
rescue Exception => ex
|
|
283
|
+
warn("ExceptionHandling.send_exception_to_sentry rescued exception while logging #{exception_info.exception_context}:\n#{exception.class}: #{exception.message}:\n#{ex.class}: #{ex.message}\n#{ex.backtrace.join("\n")}")
|
|
284
|
+
write_exception_to_log(ex, "ExceptionHandling.send_exception_to_sentry rescued exception while logging #{exception_info.exception_context}:\n#{exception.class}: #{exception.message}", exception_info.timestamp)
|
|
285
|
+
:failure
|
|
286
|
+
end
|
|
287
|
+
|
|
252
288
|
#
|
|
253
289
|
# Check if Honeybadger defined.
|
|
254
290
|
#
|
|
@@ -256,6 +292,22 @@ module ExceptionHandling # never included
|
|
|
256
292
|
Object.const_defined?("Honeybadger")
|
|
257
293
|
end
|
|
258
294
|
|
|
295
|
+
#
|
|
296
|
+
# Whether ExceptionHandling should notify Sentry. Off by default; call enable_sentry after Sentry.init.
|
|
297
|
+
#
|
|
298
|
+
def sentry_enabled?
|
|
299
|
+
!!@sentry_enabled
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
#
|
|
303
|
+
# Opt in to Sentry notifications. Requires the Sentry constant and a prior Sentry.init.
|
|
304
|
+
#
|
|
305
|
+
def enable_sentry
|
|
306
|
+
Object.const_defined?("Sentry") or raise ArgumentError, "Sentry is not defined"
|
|
307
|
+
Sentry.initialized? or raise ArgumentError, "Sentry is not initialized"
|
|
308
|
+
@sentry_enabled = true
|
|
309
|
+
end
|
|
310
|
+
|
|
259
311
|
#
|
|
260
312
|
# Expects passed in hash to only include keys which be directly set on the Honeybadger config
|
|
261
313
|
#
|
|
@@ -371,6 +423,24 @@ module ExceptionHandling # never included
|
|
|
371
423
|
).uniq
|
|
372
424
|
end
|
|
373
425
|
|
|
426
|
+
# Convert Honeybadger-style tag strings into a Sentry tags hash.
|
|
427
|
+
# Tags containing ":" are split into key/value; others become key => true.
|
|
428
|
+
#
|
|
429
|
+
# @param exception_info [ExceptionInfo]
|
|
430
|
+
# @return [Hash{String => String, TrueClass}]
|
|
431
|
+
def tags_hash_for_sentry(exception_info)
|
|
432
|
+
tags_for_honeybadger(exception_info).each_with_object({}) do |tag, hash|
|
|
433
|
+
tag = tag.to_s.strip
|
|
434
|
+
next if tag.empty?
|
|
435
|
+
|
|
436
|
+
if (separator_index = tag.index(":"))
|
|
437
|
+
hash[tag[0...separator_index]] = tag[(separator_index + 1)..]
|
|
438
|
+
else
|
|
439
|
+
hash[tag] = true
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
|
|
374
444
|
# @param exception [Exception]
|
|
375
445
|
#
|
|
376
446
|
# @return [Array<String>]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
unless ENV["NO_COVERAGE"] == "true"
|
|
4
|
+
require "simplecov"
|
|
5
|
+
|
|
6
|
+
SimpleCov.start do
|
|
7
|
+
add_filter "/spec/"
|
|
8
|
+
track_files "lib/**/*.rb"
|
|
9
|
+
|
|
10
|
+
if ENV["GITHUB_ACTIONS"]
|
|
11
|
+
require "simplecov-lcov"
|
|
12
|
+
|
|
13
|
+
SimpleCov::Formatter::LcovFormatter.config do |config|
|
|
14
|
+
config.report_with_single_file = true
|
|
15
|
+
config.single_report_path = "coverage/lcov.info"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
formatter SimpleCov::Formatter::LcovFormatter
|
|
19
|
+
else
|
|
20
|
+
formatter SimpleCov::Formatter::HTMLFormatter
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -35,6 +35,12 @@ module ExceptionHandling
|
|
|
35
35
|
expect(!ExceptionDescription.new(:filter1, error: "my error message").send_to_honeybadger).to be_truthy
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
it "allow send_to_sentry to be specified and have it disabled by default" do
|
|
39
|
+
expect(ExceptionDescription.new(:filter1, error: "my error message", send_to_sentry: false).send_to_sentry).to eq(false)
|
|
40
|
+
expect(ExceptionDescription.new(:filter1, error: "my error message", send_to_sentry: true).send_to_sentry).to eq(true)
|
|
41
|
+
expect(ExceptionDescription.new(:filter1, error: "my error message").send_to_sentry).to eq(false)
|
|
42
|
+
end
|
|
43
|
+
|
|
38
44
|
it "allow send_metric to be configured" do
|
|
39
45
|
expect(!ExceptionDescription.new(:filter1, error: "my error message", send_metric: false).send_metric).to be_truthy
|
|
40
46
|
expect(ExceptionDescription.new(:filter1, error: "my error message").send_metric).to be_truthy
|
|
@@ -452,6 +452,48 @@ module ExceptionHandling
|
|
|
452
452
|
end
|
|
453
453
|
end
|
|
454
454
|
|
|
455
|
+
context "send_to_sentry?" do
|
|
456
|
+
it "be enabled when Sentry is enabled and exception is not in the filter list" do
|
|
457
|
+
allow(ExceptionHandling).to receive(:sentry_enabled?).and_return(true)
|
|
458
|
+
exception_info = ExceptionInfo.new(StandardError.new("something went wrong"), nil, Time.now)
|
|
459
|
+
expect(exception_info.exception_description).to be_nil
|
|
460
|
+
expect(exception_info.send_to_sentry?).to eq(true)
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
it "be enabled when Sentry is enabled and filter has send_to_sentry true" do
|
|
464
|
+
allow(ExceptionHandling).to receive(:sentry_enabled?).and_return(true)
|
|
465
|
+
exception = StandardError.new("No route matches")
|
|
466
|
+
exception_info = ExceptionInfo.new(exception, nil, Time.now)
|
|
467
|
+
allow(exception_info.exception_description).to receive(:send_to_sentry).and_return(true)
|
|
468
|
+
allow(exception_info.exception_description).to receive(:send_to_honeybadger).and_return(false)
|
|
469
|
+
expect(exception_info.send_to_sentry?).to eq(true)
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it "be enabled when Sentry is enabled and filter has send_to_honeybadger true only" do
|
|
473
|
+
allow(ExceptionHandling).to receive(:sentry_enabled?).and_return(true)
|
|
474
|
+
exception = StandardError.new("No route matches")
|
|
475
|
+
exception_info = ExceptionInfo.new(exception, nil, Time.now)
|
|
476
|
+
allow(exception_info.exception_description).to receive(:send_to_sentry).and_return(false)
|
|
477
|
+
allow(exception_info.exception_description).to receive(:send_to_honeybadger).and_return(true)
|
|
478
|
+
expect(exception_info.send_to_sentry?).to eq(true)
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
it "be disabled when Sentry is enabled and both filter flags are false" do
|
|
482
|
+
allow(ExceptionHandling).to receive(:sentry_enabled?).and_return(true)
|
|
483
|
+
exception = StandardError.new("No route matches")
|
|
484
|
+
exception_info = ExceptionInfo.new(exception, nil, Time.now)
|
|
485
|
+
allow(exception_info.exception_description).to receive(:send_to_sentry).and_return(false)
|
|
486
|
+
allow(exception_info.exception_description).to receive(:send_to_honeybadger).and_return(false)
|
|
487
|
+
expect(exception_info.send_to_sentry?).to eq(false)
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
it "be disabled when Sentry is not enabled" do
|
|
491
|
+
allow(ExceptionHandling).to receive(:sentry_enabled?).and_return(false)
|
|
492
|
+
exception_info = ExceptionInfo.new(StandardError.new("something went wrong"), nil, Time.now)
|
|
493
|
+
expect(exception_info.send_to_sentry?).to eq(false)
|
|
494
|
+
end
|
|
495
|
+
end
|
|
496
|
+
|
|
455
497
|
context "honeybadger_context_data" do
|
|
456
498
|
before do
|
|
457
499
|
allow(ExceptionHandling.logger).to receive(:current_context_for_thread).and_return({ cuid: 'ABCD' })
|
|
@@ -111,6 +111,7 @@ describe ExceptionHandling do
|
|
|
111
111
|
# Reset this for every test since they are applied to the class
|
|
112
112
|
ExceptionHandling.honeybadger_auto_tagger = nil
|
|
113
113
|
ExceptionHandling.clear_honeybadger_tags_from_log_context
|
|
114
|
+
ExceptionHandling.instance_variable_set(:@sentry_enabled, false)
|
|
114
115
|
end
|
|
115
116
|
|
|
116
117
|
context "with warn and honeybadger notify stubbed" do
|
|
@@ -690,6 +691,193 @@ describe ExceptionHandling do
|
|
|
690
691
|
end
|
|
691
692
|
end
|
|
692
693
|
|
|
694
|
+
context "Sentry integration" do
|
|
695
|
+
context "enable_sentry" do
|
|
696
|
+
it "raises when Sentry is not defined" do
|
|
697
|
+
hide_const("Sentry") if Object.const_defined?("Sentry")
|
|
698
|
+
expect { ExceptionHandling.enable_sentry }.to raise_error(ArgumentError, "Sentry is not defined")
|
|
699
|
+
expect(ExceptionHandling.sentry_enabled?).to eq(false)
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
it "raises when Sentry is defined but not initialized" do
|
|
703
|
+
stub_const("Sentry", Module.new do
|
|
704
|
+
def self.initialized?; false; end
|
|
705
|
+
end)
|
|
706
|
+
expect { ExceptionHandling.enable_sentry }.to raise_error(ArgumentError, "Sentry is not initialized")
|
|
707
|
+
expect(ExceptionHandling.sentry_enabled?).to eq(false)
|
|
708
|
+
end
|
|
709
|
+
|
|
710
|
+
it "enables Sentry notifications when Sentry is defined and initialized" do
|
|
711
|
+
stub_const("Sentry", Module.new do
|
|
712
|
+
def self.initialized?; true; end
|
|
713
|
+
end)
|
|
714
|
+
ExceptionHandling.enable_sentry
|
|
715
|
+
expect(ExceptionHandling.sentry_enabled?).to eq(true)
|
|
716
|
+
end
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
context "with Sentry not enabled" do
|
|
720
|
+
it "not invoke send_exception_to_sentry when log_error is executed" do
|
|
721
|
+
expect(ExceptionHandling).to_not receive(:send_exception_to_sentry)
|
|
722
|
+
ExceptionHandling.log_error(exception_1)
|
|
723
|
+
end
|
|
724
|
+
|
|
725
|
+
it "not invoke send_exception_to_sentry when ensure_safe is executed" do
|
|
726
|
+
expect(ExceptionHandling).to_not receive(:send_exception_to_sentry)
|
|
727
|
+
ExceptionHandling.ensure_safe { raise exception_1 }
|
|
728
|
+
end
|
|
729
|
+
|
|
730
|
+
it "not send to Sentry even when the Sentry constant is defined" do
|
|
731
|
+
stub_const("Sentry", Module.new do
|
|
732
|
+
def self.initialized?; true; end
|
|
733
|
+
def self.capture_exception(_exception); end
|
|
734
|
+
end)
|
|
735
|
+
expect(Sentry).to_not receive(:capture_exception)
|
|
736
|
+
ExceptionHandling.log_error(exception_1)
|
|
737
|
+
end
|
|
738
|
+
end
|
|
739
|
+
|
|
740
|
+
context "with Sentry enabled" do
|
|
741
|
+
let(:sentry_module) do
|
|
742
|
+
Module.new do
|
|
743
|
+
def self.initialized?; true; end
|
|
744
|
+
def self.capture_exception(_exception); end
|
|
745
|
+
end
|
|
746
|
+
end
|
|
747
|
+
|
|
748
|
+
before do
|
|
749
|
+
stub_const("Sentry", sentry_module)
|
|
750
|
+
allow(Sentry).to receive(:capture_exception).and_return(Object.new)
|
|
751
|
+
ExceptionHandling.enable_sentry
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
it "not send_exception_to_sentry when log_warning is executed" do
|
|
755
|
+
expect(ExceptionHandling).to_not receive(:send_exception_to_sentry)
|
|
756
|
+
ExceptionHandling.log_warning("This should not go to sentry")
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
it "not send_exception_to_sentry when log_error is called with a Warning" do
|
|
760
|
+
expect(ExceptionHandling).to_not receive(:send_exception_to_sentry)
|
|
761
|
+
ExceptionHandling.log_error(ExceptionHandling::Warning.new("This should not go to sentry"))
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
it "invoke send_exception_to_sentry when log_error is executed" do
|
|
765
|
+
expect(ExceptionHandling).to receive(:send_exception_to_sentry).with(any_args).and_call_original
|
|
766
|
+
ExceptionHandling.log_error(exception_1)
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
it "invoke send_exception_to_sentry when log_error_rack is executed" do
|
|
770
|
+
expect(ExceptionHandling).to receive(:send_exception_to_sentry).with(any_args).and_call_original
|
|
771
|
+
ExceptionHandling.log_error_rack(exception_1, {}, nil)
|
|
772
|
+
end
|
|
773
|
+
|
|
774
|
+
it "invoke send_exception_to_sentry when ensure_safe is executed" do
|
|
775
|
+
expect(ExceptionHandling).to receive(:send_exception_to_sentry).with(any_args).and_call_original
|
|
776
|
+
ExceptionHandling.ensure_safe { raise exception_1 }
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
it "call Sentry.capture_exception with the exception" do
|
|
780
|
+
expect(Sentry).to receive(:capture_exception).with(exception_1)
|
|
781
|
+
ExceptionHandling.log_error(exception_1)
|
|
782
|
+
end
|
|
783
|
+
|
|
784
|
+
it "passes context, tags, and filter fingerprint to Sentry via the scope" do
|
|
785
|
+
scope = double("Sentry::Scope")
|
|
786
|
+
expect(scope).to receive(:set_context).with("exception_handling", hash_including(:error_class, :timestamp, :server, :backtrace))
|
|
787
|
+
expect(scope).to receive(:set_tags).with(hash_including("critical" => true, "team" => "platform"))
|
|
788
|
+
expect(scope).to receive(:set_fingerprint).with(["Test Exception"])
|
|
789
|
+
expect(scope).to receive(:set_context).with("controller", { name: "some_controller" })
|
|
790
|
+
|
|
791
|
+
expect(Sentry).to receive(:capture_exception).with(instance_of(StandardError)).and_yield(scope).and_return(Object.new)
|
|
792
|
+
|
|
793
|
+
env = { server: "fe98" }
|
|
794
|
+
parameters = { advertiser_id: 435, controller: "some_controller" }
|
|
795
|
+
session = { username: "jsmith" }
|
|
796
|
+
controller = create_dummy_controller(env, parameters, session, "host/path")
|
|
797
|
+
allow(ExceptionHandling).to receive(:server_name).and_return("invoca_fe98")
|
|
798
|
+
|
|
799
|
+
ExceptionHandling.log_error(
|
|
800
|
+
StandardError.new("Some Exception"),
|
|
801
|
+
{ "SERVER_NAME" => "exceptional.com" },
|
|
802
|
+
controller,
|
|
803
|
+
honeybadger_tags: ["critical", "team:platform"]
|
|
804
|
+
)
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
it "also notify Honeybadger when both are available" do
|
|
808
|
+
expect(Honeybadger).to receive(:notify).with(any_args).and_return("hb-id")
|
|
809
|
+
expect(Sentry).to receive(:capture_exception).with(exception_1).and_return(Object.new)
|
|
810
|
+
ExceptionHandling.log_error(exception_1)
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
it "not send to Sentry when filter has both flags false" do
|
|
814
|
+
filter_list = {
|
|
815
|
+
NoSentry: {
|
|
816
|
+
error: "suppress Sentry notification",
|
|
817
|
+
send_to_honeybadger: false,
|
|
818
|
+
send_to_sentry: false
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
allow(File).to receive(:mtime) { incrementing_mtime }
|
|
822
|
+
expect(YAML).to receive(:load_file).with(any_args) { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }.at_least(1)
|
|
823
|
+
|
|
824
|
+
expect(ExceptionHandling).to receive(:send_exception_to_sentry_unless_filtered).with(any_args).exactly(1).and_call_original
|
|
825
|
+
expect(Sentry).to_not receive(:capture_exception)
|
|
826
|
+
ExceptionHandling.log_error(StandardError.new("suppress Sentry notification"))
|
|
827
|
+
end
|
|
828
|
+
|
|
829
|
+
it "send to Sentry when filter has send_to_honeybadger true only" do
|
|
830
|
+
filter_list = {
|
|
831
|
+
HoneybadgerOnly: {
|
|
832
|
+
error: "honeybadger only filter",
|
|
833
|
+
send_to_honeybadger: true,
|
|
834
|
+
send_to_sentry: false
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
allow(File).to receive(:mtime) { incrementing_mtime }
|
|
838
|
+
expect(YAML).to receive(:load_file).with(any_args) { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }.at_least(1)
|
|
839
|
+
|
|
840
|
+
expect(Sentry).to receive(:capture_exception).with(instance_of(StandardError))
|
|
841
|
+
ExceptionHandling.log_error(StandardError.new("honeybadger only filter"))
|
|
842
|
+
end
|
|
843
|
+
|
|
844
|
+
it "send to Sentry when filter has send_to_sentry true only" do
|
|
845
|
+
filter_list = {
|
|
846
|
+
SentryOnly: {
|
|
847
|
+
error: "sentry only filter",
|
|
848
|
+
send_to_honeybadger: false,
|
|
849
|
+
send_to_sentry: true
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
allow(File).to receive(:mtime) { incrementing_mtime }
|
|
853
|
+
expect(YAML).to receive(:load_file).with(any_args) { ActiveSupport::HashWithIndifferentAccess.new(filter_list) }.at_least(1)
|
|
854
|
+
|
|
855
|
+
expect(Sentry).to receive(:capture_exception).with(instance_of(StandardError))
|
|
856
|
+
ExceptionHandling.log_error(StandardError.new("sentry only filter"))
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
it "still complete log_error and notify Honeybadger if Sentry.capture_exception raises" do
|
|
860
|
+
expect(Honeybadger).to receive(:notify).with(any_args).and_return("hb-id")
|
|
861
|
+
expect(Sentry).to receive(:capture_exception).and_raise(StandardError, "Sentry Notification Failure")
|
|
862
|
+
expect { ExceptionHandling.log_error(exception_1) }.not_to raise_error
|
|
863
|
+
end
|
|
864
|
+
|
|
865
|
+
it "return :failure when Sentry.capture_exception returns nil" do
|
|
866
|
+
expect(Sentry).to receive(:capture_exception).and_return(nil)
|
|
867
|
+
expect(ExceptionHandling.send_exception_to_sentry(
|
|
868
|
+
ExceptionHandling::ExceptionInfo.new(exception_1, "", Time.now)
|
|
869
|
+
)).to eq(:failure)
|
|
870
|
+
end
|
|
871
|
+
|
|
872
|
+
it "return :success when Sentry.capture_exception returns an event" do
|
|
873
|
+
expect(Sentry).to receive(:capture_exception).and_return(Object.new)
|
|
874
|
+
expect(ExceptionHandling.send_exception_to_sentry(
|
|
875
|
+
ExceptionHandling::ExceptionInfo.new(exception_1, "", Time.now)
|
|
876
|
+
)).to eq(:success)
|
|
877
|
+
end
|
|
878
|
+
end
|
|
879
|
+
end
|
|
880
|
+
|
|
693
881
|
class EventResponse
|
|
694
882
|
def to_s
|
|
695
883
|
"message from to_s!"
|
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: 3.1
|
|
4
|
+
version: 3.2.0.pre.dc.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: 2026-08-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -103,12 +103,13 @@ files:
|
|
|
103
103
|
- LICENSE
|
|
104
104
|
- README.md
|
|
105
105
|
- Rakefile
|
|
106
|
+
- catalog-info.yaml
|
|
106
107
|
- config/exception_filters.yml
|
|
107
108
|
- exception_handling.gemspec
|
|
108
|
-
- gemfiles/rails_6_0.gemfile
|
|
109
|
-
- gemfiles/rails_6_1.gemfile
|
|
110
109
|
- gemfiles/rails_7_0.gemfile
|
|
111
110
|
- gemfiles/rails_7_1.gemfile
|
|
111
|
+
- gemfiles/rails_7_2.gemfile
|
|
112
|
+
- gemfiles/rails_8_0.gemfile
|
|
112
113
|
- lib/exception_handling.rb
|
|
113
114
|
- lib/exception_handling/escalate_callback.rb
|
|
114
115
|
- lib/exception_handling/exception_catalog.rb
|
|
@@ -121,6 +122,7 @@ files:
|
|
|
121
122
|
- spec/helpers/controller_helpers.rb
|
|
122
123
|
- spec/helpers/exception_helpers.rb
|
|
123
124
|
- spec/rake_test_warning_false.rb
|
|
125
|
+
- spec/simplecov_helper.rb
|
|
124
126
|
- spec/spec_helper.rb
|
|
125
127
|
- spec/unit/exception_handling/escalate_callback_spec.rb
|
|
126
128
|
- spec/unit/exception_handling/exception_catalog_spec.rb
|
|
@@ -149,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
149
151
|
- !ruby/object:Gem::Version
|
|
150
152
|
version: '0'
|
|
151
153
|
requirements: []
|
|
152
|
-
rubygems_version: 3.
|
|
154
|
+
rubygems_version: 3.5.10
|
|
153
155
|
signing_key:
|
|
154
156
|
specification_version: 4
|
|
155
157
|
summary: Invoca's exception handling logger layer, based on exception_notifier.
|
|
@@ -157,6 +159,7 @@ test_files:
|
|
|
157
159
|
- spec/helpers/controller_helpers.rb
|
|
158
160
|
- spec/helpers/exception_helpers.rb
|
|
159
161
|
- spec/rake_test_warning_false.rb
|
|
162
|
+
- spec/simplecov_helper.rb
|
|
160
163
|
- spec/spec_helper.rb
|
|
161
164
|
- spec/unit/exception_handling/escalate_callback_spec.rb
|
|
162
165
|
- spec/unit/exception_handling/exception_catalog_spec.rb
|
data/gemfiles/rails_6_0.gemfile
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# This file was generated by Appraisal
|
|
2
|
-
|
|
3
|
-
source "https://rubygems.org"
|
|
4
|
-
|
|
5
|
-
gem "activesupport", "~> 6.0.0"
|
|
6
|
-
gem "appraisal", "~> 2.2"
|
|
7
|
-
gem "gem-release"
|
|
8
|
-
gem "honeybadger", "~> 4.11"
|
|
9
|
-
gem "pry"
|
|
10
|
-
gem "pry-byebug"
|
|
11
|
-
gem "rake"
|
|
12
|
-
gem "rspec"
|
|
13
|
-
gem "rspec_junit_formatter"
|
|
14
|
-
gem "rubocop"
|
|
15
|
-
gem "test-unit"
|
|
16
|
-
|
|
17
|
-
gemspec path: "../"
|
data/gemfiles/rails_6_1.gemfile
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# This file was generated by Appraisal
|
|
2
|
-
|
|
3
|
-
source "https://rubygems.org"
|
|
4
|
-
|
|
5
|
-
gem "activesupport", "~> 6.1.0"
|
|
6
|
-
gem "appraisal", "~> 2.2"
|
|
7
|
-
gem "gem-release"
|
|
8
|
-
gem "honeybadger", "~> 4.11"
|
|
9
|
-
gem "pry"
|
|
10
|
-
gem "pry-byebug"
|
|
11
|
-
gem "rake"
|
|
12
|
-
gem "rspec"
|
|
13
|
-
gem "rspec_junit_formatter"
|
|
14
|
-
gem "rubocop"
|
|
15
|
-
gem "test-unit"
|
|
16
|
-
|
|
17
|
-
gemspec path: "../"
|