bard-exception_notification 0.1.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 +7 -0
- data/.rspec +3 -0
- data/Appraisals +11 -0
- data/CLAUDE.md +30 -0
- data/LICENSE.txt +21 -0
- data/README.md +73 -0
- data/Rakefile +8 -0
- data/app/controllers/bard/exception_notification/tests_controller.rb +11 -0
- data/app/jobs/bard/exception_notification/test_job.rb +11 -0
- data/gemfiles/rails_7.2.gemfile +10 -0
- data/gemfiles/rails_8.0.gemfile +10 -0
- data/gemfiles/rails_8.1.gemfile +10 -0
- data/lib/bard/exception_notification/engine.rb +64 -0
- data/lib/bard/exception_notification/test.rb +53 -0
- data/lib/bard/exception_notification/version.rb +7 -0
- data/lib/bard/exception_notification.rb +47 -0
- data/lib/bard-exception_notification.rb +3 -0
- data/lib/tasks/exception_notification.rake +23 -0
- metadata +89 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a24301e4be9951e47b9c36677feddb1e821b1f2ce800c9981267cea23c3b62a7
|
|
4
|
+
data.tar.gz: 6ba33cc979646e6291832a1d7e00e78db3006773bda7dfcb25bd88d864eba420
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 86e2d68724422b51e9851d22c940fb9a57b59539f70815eb200e3f0776bbdf91b1ceda1dfa8899e4433b07942ac4d6ef838c9aaca1b3ebfb185dcbccc000d814
|
|
7
|
+
data.tar.gz: bd446d6a565fba957c8f82b4dadf318c78304c0ee56e1f182f672e07b252ba2172b96e92ba826bfc20910db6d5b26e70d6d175d1278d6d4756848e24fc8bb39b
|
data/.rspec
ADDED
data/Appraisals
ADDED
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What this is
|
|
6
|
+
|
|
7
|
+
A Rails engine gem that gives every BARD-managed Rails app the same exception_notification setup: email notifications for web requests, ActiveJob, rake tasks and `ActionController::Live`, plus `rake exception_notification:test` to verify delivery end to end in a deployed app.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
- Full suite (fast, under a second): `bundle exec rspec` (also `bundle exec rake`)
|
|
12
|
+
- Single file / example: `bundle exec rspec spec/bard/exception_notification_spec.rb:42`
|
|
13
|
+
- Rails matrix (as CI runs it, Ruby 3.2–4.0 × Rails 7.2/8.0/8.1): `bundle exec appraisal install`, then `bundle exec appraisal rails-7.2 rspec`
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
- `lib/bard/exception_notification.rb` holds the shared pieces: `email_options` (recipient, sender, `[<app dir name>]` subject prefix, SMTP from `credentials.exception_notification_smtp_settings`, and `sections` that deliberately omit `session`), `notify_job_failure`, and two prepend modules (`LiveErrorNotification`, `UnknownTaskNotification`).
|
|
18
|
+
- `lib/bard/exception_notification/engine.rb` wires it into the host app:
|
|
19
|
+
- The defaults initializer runs `before: :load_config_initializers`, so a host app's own `ExceptionNotification.configure` can add to (`+=`) or override the defaults. Preserve that ordering.
|
|
20
|
+
- It adds `filter_parameters` for cookie/auth/session env keys so they show as `[FILTERED]` in emails, and ignores everything outside `Rails.env.production?`.
|
|
21
|
+
- Job failures come from a `perform.active_job` notification subscriber, which fires only once retries are exhausted and never for discarded jobs.
|
|
22
|
+
- The test route is prepended with a constraint on `Test::ENV_KEY`, an env key set only in-process, so it can't be reached over HTTP.
|
|
23
|
+
- `lib/bard/exception_notification/test.rb` + `lib/tasks/exception_notification.rake` implement the end-to-end check. `Test.web` drives `Rails.application.call` with a mock request and inspects `exception_notifier.delivered`. It sets `ExceptionNotifier.testing_mode = true` so delivery failures raise instead of being only logged. The `test` task runs `web`, then `job`, then `rake`; `rake` goes last because it aborts by raising.
|
|
24
|
+
- `app/` holds the engine's `TestsController` and `TestJob` (which inherits the host's `::ApplicationJob`).
|
|
25
|
+
|
|
26
|
+
## Specs
|
|
27
|
+
|
|
28
|
+
- `spec/spec_helper.rb` defines an inline `Dummy::Application` (root `spec/dummy`), the `/boom` and `/login` routes, and the `request`/`deliveries` helpers. It stubs `Rails.env` to `production` before every example, so notifications fire by default. Tests that need "not production" re-stub it.
|
|
29
|
+
- `spec/dummy/config/initializers/exception_notification.rb` acts as a host app's initializer and switches the email notifier to `delivery_method: :test`.
|
|
30
|
+
- `module Bard::Rake` is defined in the spec helper on purpose: in real apps, bard-rake makes `Rake` inside `module Bard` resolve to `Bard::Rake`, which is why the engine uses `::Rake`. Keep top-level constants (`::Rails`, `::Rake`, `::ExceptionNotification`) fully qualified inside `module Bard`.
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Micah Geisel
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# bard-exception_notification
|
|
2
|
+
|
|
3
|
+
Shared [exception_notification](https://rubygems.org/gems/exception_notification) setup for BARD-managed Rails apps. Add the gem and every production app emails its exceptions the same way, from:
|
|
4
|
+
|
|
5
|
+
- web requests
|
|
6
|
+
- ActiveJob jobs, once retries are exhausted (discarded jobs send nothing)
|
|
7
|
+
- rake tasks, including unknown task names
|
|
8
|
+
- `ActionController::Live` actions that raise after the response has started streaming
|
|
9
|
+
|
|
10
|
+
It also adds `rake exception_notification:test` to check that notifications actually arrive from a deployed app.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
gem "bard-exception_notification"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Requires Ruby 3.2+, Rails 7.2+ and exception_notification 5.0+.
|
|
19
|
+
|
|
20
|
+
Add SMTP settings to the app's credentials:
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
exception_notification_smtp_settings:
|
|
24
|
+
address: smtp.example.com
|
|
25
|
+
port: 587
|
|
26
|
+
user_name: ...
|
|
27
|
+
password: ...
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## What it configures
|
|
31
|
+
|
|
32
|
+
- Emails go to `micah@botandrose.com` from `errors@bardtracker.com`, with the app's directory name as the subject prefix, e.g. `[myapp] `.
|
|
33
|
+
- Notifications are sent only in production.
|
|
34
|
+
- Common noise is ignored: `ActionController::InvalidAuthenticityToken`, `ActionView::MissingTemplate`, `ActionController::BadRequest`, `ActionDispatch::Http::Parameters::ParseError`, `Mime::Type::InvalidMimeType`, `URI::InvalidComponentError` and `Addressable::URI::InvalidURIError`.
|
|
35
|
+
- Cookies, the `Authorization` header and the session are kept out of emails. They are added to `filter_parameters`, and the session section is left out.
|
|
36
|
+
|
|
37
|
+
## Customizing
|
|
38
|
+
|
|
39
|
+
The defaults are applied before the app's own initializers, so an initializer can add to them or override them:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
# config/initializers/exception_notification.rb
|
|
43
|
+
ExceptionNotification.configure do |config|
|
|
44
|
+
config.ignored_exceptions += %w[MyApp::ExpectedError]
|
|
45
|
+
config.add_notifier :email, Bard::ExceptionNotification.email_options.merge(exception_recipients: "team@example.com")
|
|
46
|
+
end
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Testing a deployed app
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
bin/rake exception_notification:test
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This runs three checks in order:
|
|
56
|
+
|
|
57
|
+
- `exception_notification:test:web` sends a request through the app's middleware stack to a test page that raises, then fails unless a notification was delivered. The page is reachable only from this task, never over HTTP. The request uses the host from `Rails.application.default_url_options`, so that host must be allowed by `config.hosts`.
|
|
58
|
+
- `exception_notification:test:job` enqueues a job that raises. Its notification is sent once a worker runs the job and any retries configured by `ApplicationJob` are exhausted.
|
|
59
|
+
- `exception_notification:test:rake` raises from the task itself, so the task exits with a failure after sending its notification.
|
|
60
|
+
|
|
61
|
+
The web and rake checks raise if the notification can't be delivered, instead of only logging the failure.
|
|
62
|
+
|
|
63
|
+
## Development
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
bundle install
|
|
67
|
+
bundle exec rspec
|
|
68
|
+
bundle exec appraisal install && bundle exec appraisal rspec # every supported Rails version
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
MIT
|
data/Rakefile
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/engine"
|
|
4
|
+
|
|
5
|
+
module Bard
|
|
6
|
+
module ExceptionNotification
|
|
7
|
+
class Engine < ::Rails::Engine
|
|
8
|
+
# Before the app's own initializers, so they can adjust any of this with ExceptionNotification.configure.
|
|
9
|
+
initializer "bard-exception_notification.defaults", before: :load_config_initializers do |app|
|
|
10
|
+
app.config.filter_parameters += [
|
|
11
|
+
/\AHTTP_COOKIE\z/,
|
|
12
|
+
/\AHTTP_AUTHORIZATION\z/,
|
|
13
|
+
/\Arack\.request\.cookie_(hash|string)\z/,
|
|
14
|
+
/\Arack\.session\z/,
|
|
15
|
+
/\Aaction_dispatch\.request\.unsigned_session_cookie\z/,
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
::ExceptionNotification.configure do |config|
|
|
19
|
+
config.ignored_exceptions += %w[
|
|
20
|
+
ActionController::InvalidAuthenticityToken
|
|
21
|
+
ActionView::MissingTemplate
|
|
22
|
+
ActionController::BadRequest
|
|
23
|
+
ActionDispatch::Http::Parameters::ParseError
|
|
24
|
+
Mime::Type::InvalidMimeType
|
|
25
|
+
URI::InvalidComponentError
|
|
26
|
+
Addressable::URI::InvalidURIError
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
config.ignore_if do |exception, options|
|
|
30
|
+
!::Rails.env.production?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
config.add_notifier :email, ExceptionNotification.email_options
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
initializer "bard-exception_notification.active_job" do
|
|
38
|
+
ActiveSupport::Notifications.subscribe("perform.active_job") do |event|
|
|
39
|
+
exception = event.payload[:exception_object]
|
|
40
|
+
ExceptionNotification.notify_job_failure(exception, event.payload[:job]) if exception
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
initializer "bard-exception_notification.live" do
|
|
45
|
+
ActiveSupport.on_load(:action_controller_base) do
|
|
46
|
+
ActionController::Live.prepend LiveErrorNotification
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
initializer "bard-exception_notification.test_route" do |app|
|
|
51
|
+
app.routes.prepend do
|
|
52
|
+
get "/exception_notification/test",
|
|
53
|
+
to: "bard/exception_notification/tests#show",
|
|
54
|
+
as: nil,
|
|
55
|
+
constraints: ->(request) { request.env[Test::ENV_KEY] }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
rake_tasks do
|
|
60
|
+
::Rake::Application.prepend UnknownTaskNotification
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bard
|
|
4
|
+
module ExceptionNotification
|
|
5
|
+
class TestError < StandardError; end
|
|
6
|
+
|
|
7
|
+
module Test
|
|
8
|
+
# Set only in-process, so no HTTP request can reach the test page.
|
|
9
|
+
ENV_KEY = "bard.exception_notification.test"
|
|
10
|
+
|
|
11
|
+
extend self
|
|
12
|
+
|
|
13
|
+
def web
|
|
14
|
+
surface_delivery_failures!
|
|
15
|
+
env = ::Rack::MockRequest.env_for("https://#{host}/exception_notification/test", "HTTP_HOST" => host, ENV_KEY => true)
|
|
16
|
+
status, _headers, body = ::Rails.application.call(env)
|
|
17
|
+
body.close if body.respond_to?(:close)
|
|
18
|
+
|
|
19
|
+
raise "Expected the test page to raise #{TestError}, but it responded #{status}" unless env["action_controller.instance"].is_a?(TestsController)
|
|
20
|
+
|
|
21
|
+
exception = env["action_dispatch.exception"]
|
|
22
|
+
raise exception if exception && !exception.is_a?(TestError)
|
|
23
|
+
raise "#{TestError} from the test page was not sent; check ExceptionNotification's ignore rules" unless env["exception_notifier.delivered"]
|
|
24
|
+
puts "web: sent a #{TestError} notification from #{TestsController}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def job
|
|
28
|
+
TestJob.perform_later(message("job"))
|
|
29
|
+
puts "job: enqueued #{TestJob}; its notification is sent once the job fails for good, after any retries ApplicationJob configures"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def rake
|
|
33
|
+
surface_delivery_failures!
|
|
34
|
+
raise TestError, message("rake")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def message(context)
|
|
38
|
+
"Exception notification test from #{context} at #{Time.now.utc.iso8601}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
# Otherwise ExceptionNotifier only logs a failed delivery, and the test looks like it passed.
|
|
44
|
+
def surface_delivery_failures!
|
|
45
|
+
ExceptionNotifier.testing_mode = true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def host
|
|
49
|
+
::Rails.application.default_url_options.fetch(:host, "localhost")
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "exception_notification"
|
|
4
|
+
require "exception_notification/rails"
|
|
5
|
+
require "bard/exception_notification/version"
|
|
6
|
+
require "bard/exception_notification/test"
|
|
7
|
+
require "bard/exception_notification/engine"
|
|
8
|
+
|
|
9
|
+
module Bard
|
|
10
|
+
module ExceptionNotification
|
|
11
|
+
def self.email_options
|
|
12
|
+
{
|
|
13
|
+
email_prefix: "[#{::Rails.root.basename}] ",
|
|
14
|
+
exception_recipients: "micah@botandrose.com",
|
|
15
|
+
sender_address: "errors@bardtracker.com",
|
|
16
|
+
sections: %w[request environment backtrace], # not session, which can hold a login's persistence token
|
|
17
|
+
smtp_settings: ::Rails.application.credentials.exception_notification_smtp_settings,
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.notify_job_failure(exception, job)
|
|
22
|
+
ExceptionNotifier.notify_exception(exception, data: {
|
|
23
|
+
job_class: job.class.name,
|
|
24
|
+
job_id: job.job_id,
|
|
25
|
+
arguments: job.arguments,
|
|
26
|
+
queue_name: job.queue_name,
|
|
27
|
+
executions: job.executions,
|
|
28
|
+
})
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module LiveErrorNotification
|
|
32
|
+
def log_error(exception)
|
|
33
|
+
ExceptionNotifier.notify_exception(exception, env: request.env)
|
|
34
|
+
super
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
module UnknownTaskNotification
|
|
39
|
+
def invoke_task(task_string)
|
|
40
|
+
super
|
|
41
|
+
rescue RuntimeError => exception
|
|
42
|
+
ExceptionNotifier.notify_exception(exception) if exception.message.start_with?("Don't know how to build task")
|
|
43
|
+
raise
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :exception_notification do
|
|
4
|
+
desc "Send a test exception notification from a web request, a job and a rake task"
|
|
5
|
+
task test: %w[test:web test:job test:rake]
|
|
6
|
+
|
|
7
|
+
namespace :test do
|
|
8
|
+
desc "Send a test exception notification from a web request"
|
|
9
|
+
task web: :environment do
|
|
10
|
+
Bard::ExceptionNotification::Test.web
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
desc "Enqueue a job that fails, to send a test exception notification from a job"
|
|
14
|
+
task job: :environment do
|
|
15
|
+
Bard::ExceptionNotification::Test.job
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc "Send a test exception notification from a rake task"
|
|
19
|
+
task rake: :environment do
|
|
20
|
+
Bard::ExceptionNotification::Test.rake
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: bard-exception_notification
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Micah Geisel
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: exception_notification
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '5.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '5.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rails
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '7.2'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '7.2'
|
|
40
|
+
description: Configures exception_notification for web requests, ActiveJob, rake and
|
|
41
|
+
ActionController::Live, and adds rake exception_notification:test to check it end
|
|
42
|
+
to end
|
|
43
|
+
email:
|
|
44
|
+
- micah@botandrose.com
|
|
45
|
+
executables: []
|
|
46
|
+
extensions: []
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- ".rspec"
|
|
50
|
+
- Appraisals
|
|
51
|
+
- CLAUDE.md
|
|
52
|
+
- LICENSE.txt
|
|
53
|
+
- README.md
|
|
54
|
+
- Rakefile
|
|
55
|
+
- app/controllers/bard/exception_notification/tests_controller.rb
|
|
56
|
+
- app/jobs/bard/exception_notification/test_job.rb
|
|
57
|
+
- gemfiles/rails_7.2.gemfile
|
|
58
|
+
- gemfiles/rails_8.0.gemfile
|
|
59
|
+
- gemfiles/rails_8.1.gemfile
|
|
60
|
+
- lib/bard-exception_notification.rb
|
|
61
|
+
- lib/bard/exception_notification.rb
|
|
62
|
+
- lib/bard/exception_notification/engine.rb
|
|
63
|
+
- lib/bard/exception_notification/test.rb
|
|
64
|
+
- lib/bard/exception_notification/version.rb
|
|
65
|
+
- lib/tasks/exception_notification.rake
|
|
66
|
+
homepage: https://github.com/botandrose/bard-exception_notification
|
|
67
|
+
licenses:
|
|
68
|
+
- MIT
|
|
69
|
+
metadata:
|
|
70
|
+
homepage_uri: https://github.com/botandrose/bard-exception_notification
|
|
71
|
+
source_code_uri: https://github.com/botandrose/bard-exception_notification
|
|
72
|
+
rdoc_options: []
|
|
73
|
+
require_paths:
|
|
74
|
+
- lib
|
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: 3.2.0
|
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '0'
|
|
85
|
+
requirements: []
|
|
86
|
+
rubygems_version: 4.0.20
|
|
87
|
+
specification_version: 4
|
|
88
|
+
summary: Shared exception_notification setup for BARD-managed Rails projects
|
|
89
|
+
test_files: []
|