exception_notification 4.3.0 → 4.5.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 +5 -5
- data/Appraisals +4 -2
- data/CHANGELOG.rdoc +47 -0
- data/CONTRIBUTING.md +18 -0
- data/Gemfile +3 -1
- data/README.md +97 -945
- data/Rakefile +4 -2
- data/docs/notifiers/campfire.md +50 -0
- data/docs/notifiers/custom.md +42 -0
- data/docs/notifiers/datadog.md +51 -0
- data/docs/notifiers/email.md +195 -0
- data/docs/notifiers/google_chat.md +31 -0
- data/docs/notifiers/hipchat.md +66 -0
- data/docs/notifiers/irc.md +97 -0
- data/docs/notifiers/mattermost.md +115 -0
- data/docs/notifiers/slack.md +161 -0
- data/docs/notifiers/sns.md +37 -0
- data/docs/notifiers/teams.md +54 -0
- data/docs/notifiers/webhook.md +60 -0
- data/examples/sample_app.rb +56 -0
- data/examples/sinatra/Gemfile +8 -6
- data/examples/sinatra/config.ru +3 -1
- data/examples/sinatra/sinatra_app.rb +19 -11
- data/exception_notification.gemspec +30 -24
- data/gemfiles/{rails4_0.gemfile → rails5_2.gemfile} +2 -2
- data/gemfiles/{rails4_1.gemfile → rails6_0.gemfile} +2 -2
- data/gemfiles/{rails4_2.gemfile → rails6_1.gemfile} +2 -2
- data/gemfiles/{rails5_0.gemfile → rails7_0.gemfile} +2 -2
- data/lib/exception_notification/rack.rb +28 -30
- data/lib/exception_notification/rails.rb +2 -0
- data/lib/exception_notification/resque.rb +10 -10
- data/lib/exception_notification/sidekiq.rb +10 -12
- data/lib/exception_notification/version.rb +5 -0
- data/lib/exception_notification.rb +3 -0
- data/lib/exception_notifier/base_notifier.rb +10 -5
- data/lib/exception_notifier/datadog_notifier.rb +156 -0
- data/lib/exception_notifier/email_notifier.rb +73 -88
- data/lib/exception_notifier/google_chat_notifier.rb +27 -119
- data/lib/exception_notifier/hipchat_notifier.rb +13 -12
- data/lib/exception_notifier/irc_notifier.rb +36 -33
- data/lib/exception_notifier/mattermost_notifier.rb +54 -137
- data/lib/exception_notifier/modules/backtrace_cleaner.rb +2 -2
- data/lib/exception_notifier/modules/error_grouping.rb +24 -13
- data/lib/exception_notifier/modules/formatter.rb +125 -0
- data/lib/exception_notifier/notifier.rb +9 -6
- data/lib/exception_notifier/slack_notifier.rb +65 -40
- data/lib/exception_notifier/sns_notifier.rb +23 -13
- data/lib/exception_notifier/teams_notifier.rb +67 -46
- data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/_request.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +2 -2
- data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +2 -2
- data/lib/exception_notifier/webhook_notifier.rb +17 -14
- data/lib/exception_notifier.rb +65 -10
- data/lib/generators/exception_notification/install_generator.rb +11 -5
- data/lib/generators/exception_notification/templates/{exception_notification.rb → exception_notification.rb.erb} +13 -11
- data/test/exception_notification/rack_test.rb +75 -13
- data/test/exception_notification/resque_test.rb +54 -0
- data/test/exception_notifier/datadog_notifier_test.rb +153 -0
- data/test/exception_notifier/email_notifier_test.rb +275 -153
- data/test/exception_notifier/google_chat_notifier_test.rb +158 -101
- data/test/exception_notifier/hipchat_notifier_test.rb +84 -81
- data/test/exception_notifier/irc_notifier_test.rb +36 -34
- data/test/exception_notifier/mattermost_notifier_test.rb +213 -67
- data/test/exception_notifier/modules/error_grouping_test.rb +41 -40
- data/test/exception_notifier/modules/formatter_test.rb +152 -0
- data/test/exception_notifier/sidekiq_test.rb +9 -17
- data/test/exception_notifier/slack_notifier_test.rb +66 -63
- data/test/exception_notifier/sns_notifier_test.rb +84 -32
- data/test/exception_notifier/teams_notifier_test.rb +25 -26
- data/test/exception_notifier/webhook_notifier_test.rb +52 -48
- data/test/exception_notifier_test.rb +150 -41
- data/test/support/exception_notifier_helper.rb +14 -0
- data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.html.erb +0 -0
- data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.text.erb +0 -0
- data/test/{dummy/app → support}/views/exception_notifier/_new_section.html.erb +0 -0
- data/test/{dummy/app → support}/views/exception_notifier/_new_section.text.erb +0 -0
- data/test/test_helper.rb +14 -13
- metadata +134 -175
- data/gemfiles/rails5_1.gemfile +0 -7
- data/lib/exception_notifier/campfire_notifier.rb +0 -40
- data/test/dummy/.gitignore +0 -4
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/controllers/application_controller.rb +0 -3
- data/test/dummy/app/controllers/posts_controller.rb +0 -30
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/helpers/posts_helper.rb +0 -2
- data/test/dummy/app/models/post.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/app/views/posts/_form.html.erb +0 -0
- data/test/dummy/app/views/posts/new.html.erb +0 -0
- data/test/dummy/app/views/posts/show.html.erb +0 -0
- data/test/dummy/config/application.rb +0 -42
- data/test/dummy/config/boot.rb +0 -6
- data/test/dummy/config/database.yml +0 -22
- data/test/dummy/config/environment.rb +0 -17
- data/test/dummy/config/environments/development.rb +0 -25
- data/test/dummy/config/environments/production.rb +0 -50
- data/test/dummy/config/environments/test.rb +0 -35
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/inflections.rb +0 -10
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/secret_token.rb +0 -8
- data/test/dummy/config/initializers/session_store.rb +0 -8
- data/test/dummy/config/locales/en.yml +0 -5
- data/test/dummy/config/routes.rb +0 -3
- data/test/dummy/config.ru +0 -4
- data/test/dummy/db/migrate/20110729022608_create_posts.rb +0 -15
- data/test/dummy/db/schema.rb +0 -24
- data/test/dummy/db/seeds.rb +0 -7
- data/test/dummy/lib/tasks/.gitkeep +0 -0
- data/test/dummy/public/404.html +0 -26
- data/test/dummy/public/422.html +0 -26
- data/test/dummy/public/500.html +0 -26
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/images/rails.png +0 -0
- data/test/dummy/public/index.html +0 -239
- data/test/dummy/public/javascripts/application.js +0 -2
- data/test/dummy/public/javascripts/controls.js +0 -965
- data/test/dummy/public/javascripts/dragdrop.js +0 -974
- data/test/dummy/public/javascripts/effects.js +0 -1123
- data/test/dummy/public/javascripts/prototype.js +0 -6001
- data/test/dummy/public/javascripts/rails.js +0 -191
- data/test/dummy/public/robots.txt +0 -5
- data/test/dummy/public/stylesheets/.gitkeep +0 -0
- data/test/dummy/public/stylesheets/scaffold.css +0 -56
- data/test/dummy/script/rails +0 -6
- data/test/dummy/test/functional/posts_controller_test.rb +0 -237
- data/test/dummy/test/test_helper.rb +0 -7
- data/test/exception_notifier/campfire_notifier_test.rb +0 -120
|
@@ -1,20 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
require 'httparty'
|
|
3
5
|
|
|
4
6
|
class TeamsNotifierTest < ActiveSupport::TestCase
|
|
5
|
-
|
|
6
|
-
test "should send notification if properly configured" do
|
|
7
|
+
test 'should send notification if properly configured' do
|
|
7
8
|
options = {
|
|
8
|
-
:
|
|
9
|
+
webhook_url: 'http://localhost:8000'
|
|
9
10
|
}
|
|
10
11
|
teams_notifier = ExceptionNotifier::TeamsNotifier.new
|
|
11
12
|
teams_notifier.httparty = FakeHTTParty.new
|
|
12
13
|
|
|
13
|
-
options = teams_notifier.call ArgumentError.new(
|
|
14
|
+
options = teams_notifier.call ArgumentError.new('foo'), options
|
|
14
15
|
|
|
15
16
|
body = ActiveSupport::JSON.decode options[:body]
|
|
16
|
-
assert body.
|
|
17
|
-
assert body.
|
|
17
|
+
assert body.key? 'title'
|
|
18
|
+
assert body.key? 'sections'
|
|
18
19
|
|
|
19
20
|
sections = body['sections']
|
|
20
21
|
header = sections[0]
|
|
@@ -24,15 +25,15 @@ class TeamsNotifierTest < ActiveSupport::TestCase
|
|
|
24
25
|
assert_equal 'foo', header['activitySubtitle']
|
|
25
26
|
end
|
|
26
27
|
|
|
27
|
-
test
|
|
28
|
+
test 'should send notification with create gitlab issue link if specified' do
|
|
28
29
|
options = {
|
|
29
|
-
:
|
|
30
|
-
:
|
|
30
|
+
webhook_url: 'http://localhost:8000',
|
|
31
|
+
git_url: 'github.com/aschen'
|
|
31
32
|
}
|
|
32
33
|
teams_notifier = ExceptionNotifier::TeamsNotifier.new
|
|
33
34
|
teams_notifier.httparty = FakeHTTParty.new
|
|
34
35
|
|
|
35
|
-
options = teams_notifier.call ArgumentError.new(
|
|
36
|
+
options = teams_notifier.call ArgumentError.new('foo'), options
|
|
36
37
|
|
|
37
38
|
body = ActiveSupport::JSON.decode options[:body]
|
|
38
39
|
|
|
@@ -44,27 +45,27 @@ class TeamsNotifierTest < ActiveSupport::TestCase
|
|
|
44
45
|
|
|
45
46
|
test 'should add other HTTParty options to params' do
|
|
46
47
|
options = {
|
|
47
|
-
:
|
|
48
|
-
:
|
|
49
|
-
:
|
|
50
|
-
:
|
|
51
|
-
:
|
|
52
|
-
:
|
|
48
|
+
webhook_url: 'http://localhost:8000',
|
|
49
|
+
username: 'Test Bot',
|
|
50
|
+
avatar: 'http://site.com/icon.png',
|
|
51
|
+
basic_auth: {
|
|
52
|
+
username: 'clara',
|
|
53
|
+
password: 'password'
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
teams_notifier = ExceptionNotifier::TeamsNotifier.new
|
|
56
57
|
teams_notifier.httparty = FakeHTTParty.new
|
|
57
58
|
|
|
58
|
-
options = teams_notifier.call ArgumentError.new(
|
|
59
|
+
options = teams_notifier.call ArgumentError.new('foo'), options
|
|
59
60
|
|
|
60
|
-
assert options.
|
|
61
|
+
assert options.key? :basic_auth
|
|
61
62
|
assert 'clara', options[:basic_auth][:username]
|
|
62
63
|
assert 'password', options[:basic_auth][:password]
|
|
63
64
|
end
|
|
64
65
|
|
|
65
66
|
test "should use 'A' for exceptions count if :accumulated_errors_count option is nil" do
|
|
66
67
|
teams_notifier = ExceptionNotifier::TeamsNotifier.new
|
|
67
|
-
exception = ArgumentError.new(
|
|
68
|
+
exception = ArgumentError.new('foo')
|
|
68
69
|
teams_notifier.instance_variable_set(:@exception, exception)
|
|
69
70
|
teams_notifier.instance_variable_set(:@options, {})
|
|
70
71
|
|
|
@@ -73,11 +74,11 @@ class TeamsNotifierTest < ActiveSupport::TestCase
|
|
|
73
74
|
assert_equal 'A *ArgumentError* occurred.', header['activityTitle']
|
|
74
75
|
end
|
|
75
76
|
|
|
76
|
-
test
|
|
77
|
+
test 'should use direct errors count if :accumulated_errors_count option is 5' do
|
|
77
78
|
teams_notifier = ExceptionNotifier::TeamsNotifier.new
|
|
78
|
-
exception = ArgumentError.new(
|
|
79
|
+
exception = ArgumentError.new('foo')
|
|
79
80
|
teams_notifier.instance_variable_set(:@exception, exception)
|
|
80
|
-
teams_notifier.instance_variable_set(:@options,
|
|
81
|
+
teams_notifier.instance_variable_set(:@options, accumulated_errors_count: 5)
|
|
81
82
|
message_text = teams_notifier.send(:message_text)
|
|
82
83
|
header = message_text['sections'][0]
|
|
83
84
|
assert_equal '5 *ArgumentError* occurred.', header['activityTitle']
|
|
@@ -85,9 +86,7 @@ class TeamsNotifierTest < ActiveSupport::TestCase
|
|
|
85
86
|
end
|
|
86
87
|
|
|
87
88
|
class FakeHTTParty
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return options
|
|
89
|
+
def post(_url, options)
|
|
90
|
+
options
|
|
91
91
|
end
|
|
92
|
-
|
|
93
92
|
end
|
|
@@ -1,43 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
require 'httparty'
|
|
3
5
|
|
|
4
6
|
class WebhookNotifierTest < ActiveSupport::TestCase
|
|
5
|
-
|
|
6
|
-
test "should send webhook notification if properly configured" do
|
|
7
|
+
test 'should send webhook notification if properly configured' do
|
|
7
8
|
ExceptionNotifier::WebhookNotifier.stubs(:new).returns(Object.new)
|
|
8
|
-
webhook = ExceptionNotifier::WebhookNotifier.new(
|
|
9
|
+
webhook = ExceptionNotifier::WebhookNotifier.new(url: 'http://localhost:8000')
|
|
9
10
|
webhook.stubs(:call).returns(fake_response)
|
|
10
11
|
response = webhook.call(fake_exception)
|
|
11
12
|
|
|
12
13
|
refute_nil response
|
|
13
14
|
assert_equal response[:status], 200
|
|
14
|
-
assert_equal response[:body][:exception][:error_class],
|
|
15
|
-
assert_includes response[:body][:exception][:message],
|
|
16
|
-
assert_includes response[:body][:exception][:backtrace],
|
|
15
|
+
assert_equal response[:body][:exception][:error_class], 'ZeroDivisionError'
|
|
16
|
+
assert_includes response[:body][:exception][:message], 'divided by 0'
|
|
17
|
+
assert_includes response[:body][:exception][:backtrace], '/exception_notification/test/webhook_notifier_test.rb:48'
|
|
17
18
|
|
|
18
|
-
assert response[:body][:request][:cookies].
|
|
19
|
-
assert_equal response[:body][:request][:url],
|
|
20
|
-
assert_equal response[:body][:request][:ip_address],
|
|
21
|
-
assert response[:body][:request][:environment].
|
|
22
|
-
assert_equal response[:body][:request][:controller],
|
|
23
|
-
assert response[:body][:request][:session].
|
|
24
|
-
assert response[:body][:request][:parameters].
|
|
25
|
-
assert response[:body][:data][:extra_data].
|
|
19
|
+
assert response[:body][:request][:cookies].key?(:cookie_item1)
|
|
20
|
+
assert_equal response[:body][:request][:url], 'http://example.com/example'
|
|
21
|
+
assert_equal response[:body][:request][:ip_address], '192.168.1.1'
|
|
22
|
+
assert response[:body][:request][:environment].key?(:env_item1)
|
|
23
|
+
assert_equal response[:body][:request][:controller], '#<ControllerName:0x007f9642a04d00>'
|
|
24
|
+
assert response[:body][:request][:session].key?(:session_item1)
|
|
25
|
+
assert response[:body][:request][:parameters].key?(:controller)
|
|
26
|
+
assert response[:body][:data][:extra_data].key?(:data_item1)
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
test
|
|
29
|
+
test 'should send webhook notification with correct params data' do
|
|
29
30
|
url = 'http://localhost:8000'
|
|
30
31
|
fake_exception.stubs(:backtrace).returns('the backtrace')
|
|
31
|
-
webhook = ExceptionNotifier::WebhookNotifier.new(
|
|
32
|
+
webhook = ExceptionNotifier::WebhookNotifier.new(url: url)
|
|
32
33
|
|
|
33
34
|
HTTParty.expects(:send).with(:post, url, fake_params)
|
|
34
35
|
|
|
35
36
|
webhook.call(fake_exception)
|
|
36
37
|
end
|
|
37
38
|
|
|
38
|
-
test
|
|
39
|
+
test 'should call pre/post_callback if specified' do
|
|
39
40
|
HTTParty.stubs(:send).returns(fake_response)
|
|
40
|
-
webhook = ExceptionNotifier::WebhookNotifier.new(
|
|
41
|
+
webhook = ExceptionNotifier::WebhookNotifier.new(url: 'http://localhost:8000')
|
|
41
42
|
webhook.call(fake_exception)
|
|
42
43
|
end
|
|
43
44
|
|
|
@@ -45,50 +46,53 @@ class WebhookNotifierTest < ActiveSupport::TestCase
|
|
|
45
46
|
|
|
46
47
|
def fake_response
|
|
47
48
|
{
|
|
48
|
-
:
|
|
49
|
-
:
|
|
50
|
-
:
|
|
51
|
-
:
|
|
52
|
-
:
|
|
53
|
-
:
|
|
49
|
+
status: 200,
|
|
50
|
+
body: {
|
|
51
|
+
exception: {
|
|
52
|
+
error_class: 'ZeroDivisionError',
|
|
53
|
+
message: 'divided by 0',
|
|
54
|
+
backtrace: '/exception_notification/test/webhook_notifier_test.rb:48:in `/'
|
|
54
55
|
},
|
|
55
|
-
:
|
|
56
|
-
:
|
|
56
|
+
data: {
|
|
57
|
+
extra_data: { data_item1: 'datavalue1', data_item2: 'datavalue2' }
|
|
57
58
|
},
|
|
58
|
-
:
|
|
59
|
-
:
|
|
60
|
-
:
|
|
61
|
-
:
|
|
62
|
-
:
|
|
63
|
-
:
|
|
64
|
-
:
|
|
65
|
-
:
|
|
59
|
+
request: {
|
|
60
|
+
cookies: { cookie_item1: 'cookieitemvalue1', cookie_item2: 'cookieitemvalue2' },
|
|
61
|
+
url: 'http://example.com/example',
|
|
62
|
+
ip_address: '192.168.1.1',
|
|
63
|
+
environment: { env_item1: 'envitem1', env_item2: 'envitem2' },
|
|
64
|
+
controller: '#<ControllerName:0x007f9642a04d00>',
|
|
65
|
+
session: { session_item1: 'sessionitem1', session_item2: 'sessionitem2' },
|
|
66
|
+
parameters: { action: 'index', controller: 'projects' }
|
|
66
67
|
}
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
def fake_params
|
|
72
|
-
{
|
|
73
|
-
:
|
|
74
|
-
:
|
|
75
|
-
:
|
|
76
|
-
:
|
|
77
|
-
|
|
78
|
-
:
|
|
79
|
-
:
|
|
80
|
-
:backtrace => 'the backtrace'
|
|
73
|
+
params = {
|
|
74
|
+
body: {
|
|
75
|
+
server: Socket.gethostname,
|
|
76
|
+
process: $PROCESS_ID,
|
|
77
|
+
exception: {
|
|
78
|
+
error_class: 'ZeroDivisionError',
|
|
79
|
+
message: 'divided by 0'.inspect,
|
|
80
|
+
backtrace: 'the backtrace'
|
|
81
81
|
},
|
|
82
|
-
:
|
|
82
|
+
data: {}
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
|
|
86
|
+
params[:body][:rails_root] = Rails.root if defined?(::Rails) && Rails.respond_to?(:root)
|
|
87
|
+
|
|
88
|
+
params
|
|
85
89
|
end
|
|
86
90
|
|
|
87
91
|
def fake_exception
|
|
88
92
|
@fake_exception ||= begin
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
5 / 0
|
|
94
|
+
rescue StandardError => e
|
|
95
|
+
e
|
|
96
|
+
end
|
|
93
97
|
end
|
|
94
98
|
end
|
|
@@ -1,44 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
|
-
class ExceptionOne < StandardError;end
|
|
4
|
-
class ExceptionTwo < StandardError;end
|
|
5
|
+
class ExceptionOne < StandardError; end
|
|
6
|
+
class ExceptionTwo < StandardError; end
|
|
5
7
|
|
|
6
8
|
class ExceptionNotifierTest < ActiveSupport::TestCase
|
|
7
9
|
setup do
|
|
10
|
+
ExceptionNotifier.register_exception_notifier(:email, exception_recipients: %w[dummyexceptions@example.com])
|
|
11
|
+
|
|
8
12
|
@notifier_calls = 0
|
|
9
|
-
@test_notifier =
|
|
13
|
+
@test_notifier = ->(_exception, _options) { @notifier_calls += 1 }
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
teardown do
|
|
13
|
-
ExceptionNotifier.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Rails.cache.clear
|
|
17
|
+
ExceptionNotifier.reset_notifiers!
|
|
18
|
+
|
|
19
|
+
Rails.cache.clear if defined?(Rails) && Rails.respond_to?(:cache)
|
|
17
20
|
end
|
|
18
21
|
|
|
19
|
-
test
|
|
22
|
+
test 'should have default ignored exceptions' do
|
|
20
23
|
assert_equal ExceptionNotifier.ignored_exceptions,
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
['ActiveRecord::RecordNotFound', 'Mongoid::Errors::DocumentNotFound',
|
|
25
|
+
'AbstractController::ActionNotFound', 'ActionController::RoutingError',
|
|
26
|
+
'ActionController::UnknownFormat', 'ActionController::UrlGenerationError']
|
|
23
27
|
end
|
|
24
28
|
|
|
25
|
-
test
|
|
29
|
+
test 'should have email notifier registered' do
|
|
26
30
|
assert_equal ExceptionNotifier.notifiers, [:email]
|
|
27
31
|
end
|
|
28
32
|
|
|
29
|
-
test
|
|
33
|
+
test 'should have a valid email notifier' do
|
|
30
34
|
@email_notifier = ExceptionNotifier.registered_exception_notifier(:email)
|
|
31
35
|
refute_nil @email_notifier
|
|
32
36
|
assert_equal @email_notifier.class, ExceptionNotifier::EmailNotifier
|
|
33
37
|
assert_respond_to @email_notifier, :call
|
|
34
38
|
end
|
|
35
39
|
|
|
36
|
-
test
|
|
40
|
+
test 'should allow register/unregister another notifier' do
|
|
37
41
|
called = false
|
|
38
|
-
proc_notifier =
|
|
42
|
+
proc_notifier = ->(_exception, _options) { called = true }
|
|
39
43
|
ExceptionNotifier.register_exception_notifier(:proc, proc_notifier)
|
|
40
44
|
|
|
41
|
-
assert_equal ExceptionNotifier.notifiers.sort, [
|
|
45
|
+
assert_equal ExceptionNotifier.notifiers.sort, %i[email proc]
|
|
42
46
|
|
|
43
47
|
exception = StandardError.new
|
|
44
48
|
|
|
@@ -49,27 +53,27 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
|
|
|
49
53
|
assert_equal ExceptionNotifier.notifiers, [:email]
|
|
50
54
|
end
|
|
51
55
|
|
|
52
|
-
test
|
|
56
|
+
test 'should allow select notifiers to send error to' do
|
|
53
57
|
notifier1_calls = 0
|
|
54
|
-
notifier1 =
|
|
58
|
+
notifier1 = ->(_exception, _options) { notifier1_calls += 1 }
|
|
55
59
|
ExceptionNotifier.register_exception_notifier(:notifier1, notifier1)
|
|
56
60
|
|
|
57
61
|
notifier2_calls = 0
|
|
58
|
-
notifier2 =
|
|
62
|
+
notifier2 = ->(_exception, _options) { notifier2_calls += 1 }
|
|
59
63
|
ExceptionNotifier.register_exception_notifier(:notifier2, notifier2)
|
|
60
64
|
|
|
61
|
-
assert_equal ExceptionNotifier.notifiers.sort, [
|
|
65
|
+
assert_equal ExceptionNotifier.notifiers.sort, %i[email notifier1 notifier2]
|
|
62
66
|
|
|
63
67
|
exception = StandardError.new
|
|
64
68
|
ExceptionNotifier.notify_exception(exception)
|
|
65
69
|
assert_equal notifier1_calls, 1
|
|
66
70
|
assert_equal notifier2_calls, 1
|
|
67
71
|
|
|
68
|
-
ExceptionNotifier.notify_exception(exception,
|
|
72
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :notifier1)
|
|
69
73
|
assert_equal notifier1_calls, 2
|
|
70
74
|
assert_equal notifier2_calls, 1
|
|
71
75
|
|
|
72
|
-
ExceptionNotifier.notify_exception(exception,
|
|
76
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :notifier2)
|
|
73
77
|
assert_equal notifier1_calls, 2
|
|
74
78
|
assert_equal notifier2_calls, 2
|
|
75
79
|
|
|
@@ -78,39 +82,112 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
|
|
|
78
82
|
assert_equal ExceptionNotifier.notifiers, [:email]
|
|
79
83
|
end
|
|
80
84
|
|
|
81
|
-
test
|
|
82
|
-
env =
|
|
83
|
-
ExceptionNotifier.ignore_if do |
|
|
84
|
-
env !=
|
|
85
|
+
test 'should ignore exception if satisfies conditional ignore' do
|
|
86
|
+
env = 'production'
|
|
87
|
+
ExceptionNotifier.ignore_if do |_exception, _options|
|
|
88
|
+
env != 'production'
|
|
85
89
|
end
|
|
86
90
|
|
|
87
91
|
ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
|
|
88
92
|
|
|
89
93
|
exception = StandardError.new
|
|
90
94
|
|
|
91
|
-
ExceptionNotifier.notify_exception(exception,
|
|
95
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test)
|
|
92
96
|
assert_equal @notifier_calls, 1
|
|
93
97
|
|
|
94
|
-
env =
|
|
95
|
-
ExceptionNotifier.notify_exception(exception,
|
|
98
|
+
env = 'development'
|
|
99
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test)
|
|
96
100
|
assert_equal @notifier_calls, 1
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
test 'should ignore exception if satisfies by-notifier conditional ignore' do
|
|
104
|
+
notifier1_calls = 0
|
|
105
|
+
notifier1 = ->(_exception, _options) { notifier1_calls += 1 }
|
|
106
|
+
ExceptionNotifier.register_exception_notifier(:notifier1, notifier1)
|
|
107
|
+
|
|
108
|
+
notifier2_calls = 0
|
|
109
|
+
notifier2 = ->(_exception, _options) { notifier2_calls += 1 }
|
|
110
|
+
ExceptionNotifier.register_exception_notifier(:notifier2, notifier2)
|
|
111
|
+
|
|
112
|
+
env = 'production'
|
|
113
|
+
ExceptionNotifier.ignore_notifier_if(:notifier1) do |_exception, _options|
|
|
114
|
+
env == 'development'
|
|
115
|
+
end
|
|
116
|
+
ExceptionNotifier.ignore_notifier_if(:notifier2) do |_exception, _options|
|
|
117
|
+
env == 'production'
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
exception = StandardError.new
|
|
121
|
+
|
|
122
|
+
ExceptionNotifier.notify_exception(exception)
|
|
123
|
+
assert_equal notifier1_calls, 1
|
|
124
|
+
assert_equal notifier2_calls, 0
|
|
125
|
+
|
|
126
|
+
env = 'development'
|
|
127
|
+
|
|
128
|
+
ExceptionNotifier.notify_exception(exception)
|
|
129
|
+
assert_equal notifier1_calls, 1
|
|
130
|
+
assert_equal notifier2_calls, 1
|
|
131
|
+
|
|
132
|
+
env = 'test'
|
|
133
|
+
|
|
134
|
+
ExceptionNotifier.notify_exception(exception)
|
|
135
|
+
assert_equal notifier1_calls, 2
|
|
136
|
+
assert_equal notifier2_calls, 2
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
test 'should return false if all the registered notifiers are ignored' do
|
|
140
|
+
ExceptionNotifier.notifiers.each do |notifier|
|
|
141
|
+
# make sure to register no other notifiers but the tested ones
|
|
142
|
+
ExceptionNotifier.unregister_exception_notifier(notifier)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
ExceptionNotifier.register_exception_notifier(:notifier1, ->(_, _) {})
|
|
146
|
+
ExceptionNotifier.register_exception_notifier(:notifier2, ->(_, _) {})
|
|
147
|
+
|
|
148
|
+
ExceptionNotifier.ignore_notifier_if(:notifier1) do |exception, _options|
|
|
149
|
+
exception.message =~ /non_critical_error/
|
|
150
|
+
end
|
|
151
|
+
ExceptionNotifier.ignore_notifier_if(:notifier2) do |exception, _options|
|
|
152
|
+
exception.message =~ /non_critical_error/
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
exception = StandardError.new('a non_critical_error occured.')
|
|
97
156
|
|
|
98
|
-
ExceptionNotifier.
|
|
157
|
+
refute ExceptionNotifier.notify_exception(exception)
|
|
99
158
|
end
|
|
100
159
|
|
|
101
|
-
test
|
|
160
|
+
test 'should return true if one of the notifiers fires' do
|
|
161
|
+
ExceptionNotifier.notifiers.each do |notifier|
|
|
162
|
+
# make sure to register no other notifiers but the tested ones
|
|
163
|
+
ExceptionNotifier.unregister_exception_notifier(notifier)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
ExceptionNotifier.register_exception_notifier(:notifier1, ->(_, _) {})
|
|
167
|
+
ExceptionNotifier.register_exception_notifier(:notifier2, ->(_, _) {})
|
|
168
|
+
|
|
169
|
+
ExceptionNotifier.ignore_notifier_if(:notifier1) do |exception, _options|
|
|
170
|
+
exception.message =~ /non-critical\serror/
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
exception = StandardError.new('a non-critical error occured')
|
|
174
|
+
|
|
175
|
+
assert ExceptionNotifier.notify_exception(exception)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
test 'should not send notification if one of ignored exceptions' do
|
|
102
179
|
ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
|
|
103
180
|
|
|
104
181
|
exception = StandardError.new
|
|
105
182
|
|
|
106
|
-
ExceptionNotifier.notify_exception(exception,
|
|
183
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test)
|
|
107
184
|
assert_equal @notifier_calls, 1
|
|
108
185
|
|
|
109
|
-
ExceptionNotifier.notify_exception(exception,
|
|
186
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test, ignore_exceptions: 'StandardError')
|
|
110
187
|
assert_equal @notifier_calls, 1
|
|
111
188
|
end
|
|
112
189
|
|
|
113
|
-
test
|
|
190
|
+
test 'should not send notification if subclass of one of ignored exceptions' do
|
|
114
191
|
ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
|
|
115
192
|
|
|
116
193
|
class StandardErrorSubclass < StandardError
|
|
@@ -118,16 +195,48 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
|
|
|
118
195
|
|
|
119
196
|
exception = StandardErrorSubclass.new
|
|
120
197
|
|
|
121
|
-
ExceptionNotifier.notify_exception(exception,
|
|
198
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test)
|
|
199
|
+
assert_equal @notifier_calls, 1
|
|
200
|
+
|
|
201
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test, ignore_exceptions: 'StandardError')
|
|
202
|
+
assert_equal @notifier_calls, 1
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
test 'should not send notification if extended module one of ignored exceptions' do
|
|
206
|
+
ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
|
|
207
|
+
|
|
208
|
+
module StandardErrorModule; end
|
|
209
|
+
|
|
210
|
+
exception = StandardError.new
|
|
211
|
+
exception.extend StandardErrorModule
|
|
212
|
+
|
|
213
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test)
|
|
214
|
+
assert_equal @notifier_calls, 1
|
|
215
|
+
|
|
216
|
+
ignore_exceptions = 'ExceptionNotifierTest::StandardErrorModule'
|
|
217
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test, ignore_exceptions: ignore_exceptions)
|
|
218
|
+
assert_equal @notifier_calls, 1
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
test 'should not send notification if prepended module at singleton class one of ignored exceptions' do
|
|
222
|
+
ExceptionNotifier.register_exception_notifier(:test, @test_notifier)
|
|
223
|
+
|
|
224
|
+
module StandardErrorModule; end
|
|
225
|
+
|
|
226
|
+
exception = StandardError.new
|
|
227
|
+
exception.singleton_class.prepend StandardErrorModule
|
|
228
|
+
|
|
229
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test)
|
|
122
230
|
assert_equal @notifier_calls, 1
|
|
123
231
|
|
|
124
|
-
|
|
232
|
+
ignore_exceptions = 'ExceptionNotifierTest::StandardErrorModule'
|
|
233
|
+
ExceptionNotifier.notify_exception(exception, notifiers: :test, ignore_exceptions: ignore_exceptions)
|
|
125
234
|
assert_equal @notifier_calls, 1
|
|
126
235
|
end
|
|
127
236
|
|
|
128
|
-
test
|
|
237
|
+
test 'should call received block' do
|
|
129
238
|
@block_called = false
|
|
130
|
-
notifier =
|
|
239
|
+
notifier = ->(_exception, _options, &block) { block.call }
|
|
131
240
|
ExceptionNotifier.register_exception_notifier(:test, notifier)
|
|
132
241
|
|
|
133
242
|
exception = ExceptionOne.new
|
|
@@ -139,7 +248,7 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
|
|
|
139
248
|
assert @block_called
|
|
140
249
|
end
|
|
141
250
|
|
|
142
|
-
test
|
|
251
|
+
test 'should not call group_error! or send_notification? if error_grouping false' do
|
|
143
252
|
exception = StandardError.new
|
|
144
253
|
ExceptionNotifier.expects(:group_error!).never
|
|
145
254
|
ExceptionNotifier.expects(:send_notification?).never
|
|
@@ -147,7 +256,7 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
|
|
|
147
256
|
ExceptionNotifier.notify_exception(exception)
|
|
148
257
|
end
|
|
149
258
|
|
|
150
|
-
test
|
|
259
|
+
test 'should call group_error! and send_notification? if error_grouping true' do
|
|
151
260
|
ExceptionNotifier.error_grouping = true
|
|
152
261
|
|
|
153
262
|
exception = StandardError.new
|
|
@@ -157,7 +266,7 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
|
|
|
157
266
|
ExceptionNotifier.notify_exception(exception)
|
|
158
267
|
end
|
|
159
268
|
|
|
160
|
-
test
|
|
269
|
+
test 'should skip notification if send_notification? is false' do
|
|
161
270
|
ExceptionNotifier.error_grouping = true
|
|
162
271
|
|
|
163
272
|
exception = StandardError.new
|
|
@@ -167,7 +276,7 @@ class ExceptionNotifierTest < ActiveSupport::TestCase
|
|
|
167
276
|
refute ExceptionNotifier.notify_exception(exception)
|
|
168
277
|
end
|
|
169
278
|
|
|
170
|
-
test
|
|
279
|
+
test 'should send notification if send_notification? is true' do
|
|
171
280
|
ExceptionNotifier.error_grouping = true
|
|
172
281
|
|
|
173
282
|
exception = StandardError.new
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# this extension allows ExceptionNotifier to reset all the glocal settings
|
|
4
|
+
# (i.e. class vars that otherwise remains during the test)
|
|
5
|
+
# please remembeer to call this method each time after you set such settings
|
|
6
|
+
# to prevent order dependent test fails.
|
|
7
|
+
module ExceptionNotifier
|
|
8
|
+
def self.reset_notifiers!
|
|
9
|
+
@@notifiers = {}
|
|
10
|
+
clear_ignore_conditions!
|
|
11
|
+
ExceptionNotifier.error_grouping = false
|
|
12
|
+
ExceptionNotifier.notification_trigger = nil
|
|
13
|
+
end
|
|
14
|
+
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/test/test_helper.rb
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
#
|
|
2
|
-
ENV["RAILS_ENV"] = "test"
|
|
1
|
+
# frozen_string_literal: true
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Coveralls.wear!
|
|
7
|
-
rescue LoadError
|
|
8
|
-
warn "warning: coveralls gem not found; skipping Coveralls"
|
|
9
|
-
end
|
|
3
|
+
require 'coveralls'
|
|
4
|
+
Coveralls.wear!
|
|
10
5
|
|
|
11
|
-
|
|
12
|
-
require
|
|
13
|
-
require File.expand_path("../dummy/test/test_helper.rb", __FILE__)
|
|
6
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
|
7
|
+
require 'exception_notification'
|
|
14
8
|
|
|
15
|
-
require
|
|
9
|
+
require 'minitest/autorun'
|
|
10
|
+
require 'mocha/minitest'
|
|
11
|
+
require 'active_support/test_case'
|
|
12
|
+
require 'action_mailer'
|
|
16
13
|
|
|
17
|
-
Rails.backtrace_cleaner.remove_silencers!
|
|
18
14
|
ExceptionNotifier.testing_mode!
|
|
15
|
+
require 'support/exception_notifier_helper'
|
|
16
|
+
|
|
17
|
+
Time.zone = 'UTC'
|
|
18
|
+
ActionMailer::Base.delivery_method = :test
|
|
19
|
+
ActionMailer::Base.append_view_path "#{File.dirname(__FILE__)}/support/views"
|