Skip to content

Commit d50b105

Browse files
committed
Including exception-notification implementations
1 parent 59bbf90 commit d50b105

35 files changed

+1558
-84
lines changed

.github/workflows/build.yml

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,27 @@ jobs:
88
fail-fast: false
99
matrix:
1010
include:
11-
- ruby: 2.7
12-
gemfile: Gemfile
13-
postgres: 13
11+
- ruby: 2.7
12+
gemfile: Gemfile
13+
- ruby: 3.0
14+
gemfile: gemfiles/Gemfile-7-0
15+
- ruby: 2.7
16+
gemfile: gemfiles/Gemfile-6-1
17+
- ruby: 2.6
18+
gemfile: gemfiles/Gemfile-6-0
19+
- ruby: 2.6
20+
gemfile: gemfiles/Gemfile-5-2
1421
env:
1522
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
1623
USE_OFFICIAL_GEM_SOURCE: 1
1724
steps:
18-
- uses: actions/checkout@v2
19-
- uses: ruby/setup-ruby@v1
20-
with:
21-
ruby-version: ${{ matrix.ruby }}
22-
bundler-cache: true
23-
- uses: ankane/setup-postgres@v1
24-
with:
25-
postgres-version: ${{ matrix.postgres }}
26-
- run: createdb dummy_test
27-
- run: bundle exec rails test
25+
- uses: actions/checkout@v2
26+
- uses: ruby/setup-ruby@v1
27+
with:
28+
ruby-version: ${{ matrix.ruby }}
29+
bundler-cache: true
30+
- uses: ankane/setup-postgres@v1
31+
with:
32+
postgres-version: 13
33+
- run: createdb dummy_test
34+
- run: bundle exec rails test

Gemfile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,3 @@
33
source "https://rubygems.org"
44

55
gemspec
6-
gem "pg"
7-
gem "codecov"
8-
gem "simplecov"

Gemfile.lock

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ PATH
22
remote: .
33
specs:
44
exception-track (1.2.0)
5-
exception_notification (~> 4)
65
kaminari (>= 0.15)
76
rails (>= 5.2)
87

@@ -69,21 +68,14 @@ GEM
6968
tzinfo (~> 2.0)
7069
zeitwerk (~> 2.3)
7170
builder (3.2.4)
72-
codecov (0.2.12)
73-
json
74-
simplecov
7571
concurrent-ruby (1.1.7)
72+
connection_pool (2.2.5)
7673
crass (1.0.6)
77-
docile (1.3.2)
7874
erubi (1.10.0)
79-
exception_notification (4.4.3)
80-
actionmailer (>= 4.0, < 7)
81-
activesupport (>= 4.0, < 7)
8275
globalid (0.4.2)
8376
activesupport (>= 4.2.0)
8477
i18n (1.8.5)
8578
concurrent-ruby (~> 1.0)
86-
json (2.4.0)
8779
kaminari (1.2.1)
8880
activesupport (>= 4.1.0)
8981
kaminari-actionview (= 1.2.1)
@@ -104,15 +96,25 @@ GEM
10496
marcel (0.3.3)
10597
mimemagic (~> 0.3.2)
10698
method_source (1.0.0)
107-
mimemagic (0.3.5)
99+
mimemagic (0.3.10)
100+
nokogiri (~> 1)
101+
rake
108102
mini_mime (1.0.2)
109-
mini_portile2 (2.4.0)
103+
mini_portile2 (2.6.1)
110104
minitest (5.14.2)
105+
mocha (1.13.0)
106+
mock_redis (0.19.0)
107+
mustermann (1.1.1)
108+
ruby2_keywords (~> 0.0.1)
111109
nio4r (2.5.4)
112-
nokogiri (1.10.10)
113-
mini_portile2 (~> 2.4.0)
110+
nokogiri (1.12.5)
111+
mini_portile2 (~> 2.6.1)
112+
racc (~> 1.4)
114113
pg (1.2.3)
114+
racc (1.6.0)
115115
rack (2.2.3)
116+
rack-protection (2.1.0)
117+
rack
116118
rack-test (1.1.0)
117119
rack (>= 1.0, < 3)
118120
rails (6.1.0)
@@ -142,12 +144,24 @@ GEM
142144
rake (>= 0.8.7)
143145
thor (~> 1.0)
144146
rake (13.0.1)
145-
simplecov (0.20.0)
146-
docile (~> 1.1)
147-
simplecov-html (~> 0.11)
148-
simplecov_json_formatter (~> 0.1)
149-
simplecov-html (0.12.3)
150-
simplecov_json_formatter (0.1.2)
147+
redis (4.5.1)
148+
redis-namespace (1.8.1)
149+
redis (>= 3.0.4)
150+
resque (1.8.2)
151+
redis
152+
redis-namespace
153+
sinatra (>= 0.9.2)
154+
vegas (>= 0.1.2)
155+
ruby2_keywords (0.0.5)
156+
sidekiq (6.3.1)
157+
connection_pool (>= 2.2.2)
158+
rack (~> 2.0)
159+
redis (>= 4.2.0)
160+
sinatra (2.1.0)
161+
mustermann (~> 1.0)
162+
rack (~> 2.2)
163+
rack-protection (= 2.1.0)
164+
tilt (~> 2.0)
151165
sprockets (4.0.2)
152166
concurrent-ruby (~> 1.0)
153167
rack (> 1, < 3)
@@ -156,8 +170,12 @@ GEM
156170
activesupport (>= 4.0)
157171
sprockets (>= 3.0.0)
158172
thor (1.0.1)
173+
tilt (2.0.10)
174+
timecop (0.9.4)
159175
tzinfo (2.0.3)
160176
concurrent-ruby (~> 1.0)
177+
vegas (0.1.11)
178+
rack (>= 1.0.0)
161179
websocket-driver (0.7.3)
162180
websocket-extensions (>= 0.1.0)
163181
websocket-extensions (0.1.5)
@@ -167,10 +185,13 @@ PLATFORMS
167185
ruby
168186

169187
DEPENDENCIES
170-
codecov
171188
exception-track!
172-
pg
173-
simplecov
189+
mocha (>= 0.13.0)
190+
mock_redis (~> 0.19.0)
191+
pg (>= 1)
192+
resque (~> 1.8.0)
193+
sidekiq (>= 5.0.4)
194+
timecop (~> 0.9.0)
174195

175196
BUNDLED WITH
176-
2.1.4
197+
2.2.22

exception-track.gemspec

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,23 @@ require "exception-track/version"
77

88
# Describe your gem and declare its dependencies:
99
Gem::Specification.new do |s|
10-
s.name = "exception-track"
11-
s.version = ExceptionTrack::VERSION
12-
s.authors = ["Jason Lee"]
13-
s.email = ["[email protected]"]
14-
s.homepage = "https://github.com/rails-engine/exception-track"
15-
s.summary = "Tracking exceptions for Rails application store them in database."
10+
s.name = "exception-track"
11+
s.version = ExceptionTrack::VERSION
12+
s.authors = ["Jason Lee"]
13+
s.email = ["[email protected]"]
14+
s.homepage = "https://github.com/rails-engine/exception-track"
15+
s.summary = "Tracking exceptions for Rails application store them in database."
1616
s.description = "Tracking exceptions for Rails application store them in database by exception_notification gem."
17-
s.license = "MIT"
17+
s.license = "MIT"
1818

1919
s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "README.md"]
2020

21-
s.add_dependency "exception_notification", "~> 4"
2221
s.add_dependency "kaminari", ">= 0.15"
2322
s.add_dependency "rails", ">= 5.2"
23+
s.add_development_dependency "pg", ">= 1"
24+
s.add_development_dependency "mocha", ">= 0.13.0"
25+
s.add_development_dependency "mock_redis", "~> 0.19.0"
26+
s.add_development_dependency "resque", "~> 1.8.0"
27+
s.add_development_dependency "sidekiq", ">= 5.0.4"
28+
s.add_development_dependency "timecop", "~> 0.9.0"
2429
end

gemfiles/Gemfile-5-2

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source "https://rubygems.org"
2+
3+
gem "rails", "~> 5.2.0"
4+
5+
gemspec path: "../"

gemfiles/Gemfile-6-0

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source "https://rubygems.org"
2+
3+
gem "rails", "~> 6.0.0"
4+
5+
gemspec path: "../"

gemfiles/Gemfile-6-1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source "https://rubygems.org"
2+
3+
gem "rails", "~> 6.1.0"
4+
5+
gemspec path: "../"

gemfiles/Gemfile-7-0

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source "https://rubygems.org"
2+
3+
gem "rails", "~> 7.0.0"
4+
5+
gemspec path: "../"

lib/exception-track.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
require "exception_notification"
99
require "exception_notification/rails"
10-
require "exception_notifier/exception_track_notifier"
1110

1211
require "kaminari"
1312

@@ -28,5 +27,5 @@ def configure(&block)
2827
end
2928

3029
ExceptionNotification.configure do |config|
31-
config.add_notifier :exception_track, {}
30+
config.add_notifier :db, {}
3231
end

lib/exception_notification.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# frozen_string_literal: true
2+
3+
require "exception_notifier/notifier"
4+
require "exception_notification/rack"
5+
require "exception_notification/version"
6+
7+
module ExceptionNotification
8+
# Alternative way to setup ExceptionNotification.
9+
# Run 'rails generate exception_notification:install' to create
10+
# a fresh initializer with all configuration values.
11+
def self.configure
12+
yield ExceptionNotifier
13+
end
14+
end

lib/exception_notification/rack.rb

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# frozen_string_literal: true
2+
3+
module ExceptionNotification
4+
class Rack
5+
class CascadePassException < RuntimeError; end
6+
7+
def initialize(app, options = {})
8+
@app = app
9+
10+
ExceptionNotifier.tap do |en|
11+
en.ignored_exceptions = options.delete(:ignore_exceptions) if options.key?(:ignore_exceptions)
12+
en.error_grouping = options.delete(:error_grouping) if options.key?(:error_grouping)
13+
en.error_grouping_period = options.delete(:error_grouping_period) if options.key?(:error_grouping_period)
14+
en.notification_trigger = options.delete(:notification_trigger) if options.key?(:notification_trigger)
15+
16+
if options.key?(:error_grouping_cache)
17+
en.error_grouping_cache = options.delete(:error_grouping_cache)
18+
elsif defined?(Rails) && Rails.respond_to?(:cache)
19+
en.error_grouping_cache = Rails.cache
20+
end
21+
end
22+
23+
if options.key?(:ignore_if)
24+
rack_ignore = options.delete(:ignore_if)
25+
ExceptionNotifier.ignore_if do |exception, opts|
26+
opts.key?(:env) && rack_ignore.call(opts[:env], exception)
27+
end
28+
end
29+
30+
if options.key?(:ignore_notifier_if)
31+
rack_ignore_by_notifier = options.delete(:ignore_notifier_if)
32+
rack_ignore_by_notifier.each do |notifier, proc|
33+
ExceptionNotifier.ignore_notifier_if(notifier) do |exception, opts|
34+
opts.key?(:env) && proc.call(opts[:env], exception)
35+
end
36+
end
37+
end
38+
39+
ExceptionNotifier.ignore_crawlers(options.delete(:ignore_crawlers)) if options.key?(:ignore_crawlers)
40+
41+
@ignore_cascade_pass = options.delete(:ignore_cascade_pass) { true }
42+
43+
options.each do |notifier_name, opts|
44+
ExceptionNotifier.register_exception_notifier(notifier_name, opts)
45+
end
46+
end
47+
48+
def call(env)
49+
_, headers, = response = @app.call(env)
50+
51+
if !@ignore_cascade_pass && headers["X-Cascade"] == "pass"
52+
msg = "This exception means that the preceding Rack middleware set the 'X-Cascade' header to 'pass' -- in " \
53+
"Rails, this often means that the route was not found (404 error)."
54+
raise CascadePassException, msg
55+
end
56+
57+
response
58+
rescue Exception => e
59+
env["exception_notifier.delivered"] = true if ExceptionNotifier.notify_exception(e, env: env)
60+
61+
raise e unless e.is_a?(CascadePassException)
62+
63+
response
64+
end
65+
end
66+
end

lib/exception_notification/rails.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
3+
module ExceptionNotification
4+
class Engine < ::Rails::Engine
5+
config.exception_notification = ExceptionNotifier
6+
config.exception_notification.logger = Rails.logger
7+
config.exception_notification.error_grouping_cache = Rails.cache
8+
9+
config.app_middleware.use ExceptionNotification::Rack
10+
end
11+
end

lib/exception_notification/resque.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# frozen_string_literal: true
2+
3+
require "resque/failure/base"
4+
5+
module ExceptionNotification
6+
class Resque < Resque::Failure::Base
7+
def self.count
8+
::Resque::Stat[:failed]
9+
end
10+
11+
def save
12+
data = {
13+
error_class: exception.class.name,
14+
error_message: exception.message,
15+
failed_at: Time.now.to_s,
16+
payload: payload,
17+
queue: queue,
18+
worker: worker.to_s
19+
}
20+
21+
ExceptionNotifier.notify_exception(exception, data: {resque: data})
22+
end
23+
end
24+
end

lib/exception_notification/sidekiq.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
require "sidekiq"
4+
5+
# Note: this class is only needed for Sidekiq version < 3.
6+
module ExceptionNotification
7+
class Sidekiq
8+
def call(_worker, msg, _queue)
9+
yield
10+
rescue Exception => e
11+
ExceptionNotifier.notify_exception(e, data: {sidekiq: msg})
12+
raise e
13+
end
14+
end
15+
end
16+
17+
if ::Sidekiq::VERSION < "3"
18+
::Sidekiq.configure_server do |config|
19+
config.server_middleware do |chain|
20+
chain.add ::ExceptionNotification::Sidekiq
21+
end
22+
end
23+
else
24+
::Sidekiq.configure_server do |config|
25+
config.error_handlers << proc do |ex, context|
26+
ExceptionNotifier.notify_exception(ex, data: {sidekiq: context})
27+
end
28+
end
29+
end

lib/exception_notification/version.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# frozen_string_literal: true
2+
3+
module ExceptionNotification
4+
VERSION = "4.5.0"
5+
end

0 commit comments

Comments
 (0)