exception_notification_more_info 1.0.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.
Files changed (118) hide show
  1. checksums.yaml +7 -0
  2. data/Appraisals +7 -0
  3. data/CHANGELOG.rdoc +141 -0
  4. data/CODE_OF_CONDUCT.md +22 -0
  5. data/CONTRIBUTING.md +42 -0
  6. data/Gemfile +3 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +839 -0
  9. data/Rakefile +23 -0
  10. data/examples/sinatra/Gemfile +8 -0
  11. data/examples/sinatra/Gemfile.lock +95 -0
  12. data/examples/sinatra/Procfile +2 -0
  13. data/examples/sinatra/README.md +11 -0
  14. data/examples/sinatra/config.ru +3 -0
  15. data/examples/sinatra/sinatra_app.rb +32 -0
  16. data/exception_notification_more_info.gemspec +34 -0
  17. data/gemfiles/rails4_0.gemfile +7 -0
  18. data/gemfiles/rails4_1.gemfile +7 -0
  19. data/gemfiles/rails4_2.gemfile +7 -0
  20. data/lib/exception_notification.rb +11 -0
  21. data/lib/exception_notification/rack.rb +59 -0
  22. data/lib/exception_notification/rails.rb +8 -0
  23. data/lib/exception_notification/resque.rb +24 -0
  24. data/lib/exception_notification/sidekiq.rb +31 -0
  25. data/lib/exception_notifier.rb +121 -0
  26. data/lib/exception_notifier/base_notifier.rb +25 -0
  27. data/lib/exception_notifier/campfire_notifier.rb +36 -0
  28. data/lib/exception_notifier/email_notifier.rb +204 -0
  29. data/lib/exception_notifier/hipchat_notifier.rb +45 -0
  30. data/lib/exception_notifier/irc_notifier.rb +51 -0
  31. data/lib/exception_notifier/modules/backtrace_cleaner.rb +13 -0
  32. data/lib/exception_notifier/notifier.rb +16 -0
  33. data/lib/exception_notifier/slack_notifier.rb +73 -0
  34. data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +3 -0
  35. data/lib/exception_notifier/views/exception_notifier/_backtrace.text.erb +1 -0
  36. data/lib/exception_notifier/views/exception_notifier/_data.html.erb +6 -0
  37. data/lib/exception_notifier/views/exception_notifier/_data.text.erb +1 -0
  38. data/lib/exception_notifier/views/exception_notifier/_environment.html.erb +10 -0
  39. data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +5 -0
  40. data/lib/exception_notifier/views/exception_notifier/_request.html.erb +36 -0
  41. data/lib/exception_notifier/views/exception_notifier/_request.text.erb +10 -0
  42. data/lib/exception_notifier/views/exception_notifier/_session.html.erb +10 -0
  43. data/lib/exception_notifier/views/exception_notifier/_session.text.erb +2 -0
  44. data/lib/exception_notifier/views/exception_notifier/_title.html.erb +3 -0
  45. data/lib/exception_notifier/views/exception_notifier/_title.text.erb +3 -0
  46. data/lib/exception_notifier/views/exception_notifier/background_exception_notification.html.erb +53 -0
  47. data/lib/exception_notifier/views/exception_notifier/background_exception_notification.text.erb +14 -0
  48. data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +54 -0
  49. data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +24 -0
  50. data/lib/exception_notifier/webhook_notifier.rb +47 -0
  51. data/lib/generators/exception_notification/install_generator.rb +15 -0
  52. data/lib/generators/exception_notification/templates/exception_notification.rb +53 -0
  53. data/test/dummy/.gitignore +4 -0
  54. data/test/dummy/Gemfile +34 -0
  55. data/test/dummy/Gemfile.lock +137 -0
  56. data/test/dummy/Rakefile +7 -0
  57. data/test/dummy/app/controllers/application_controller.rb +3 -0
  58. data/test/dummy/app/controllers/posts_controller.rb +30 -0
  59. data/test/dummy/app/helpers/application_helper.rb +2 -0
  60. data/test/dummy/app/helpers/posts_helper.rb +2 -0
  61. data/test/dummy/app/models/post.rb +2 -0
  62. data/test/dummy/app/views/exception_notifier/_new_bkg_section.html.erb +1 -0
  63. data/test/dummy/app/views/exception_notifier/_new_bkg_section.text.erb +1 -0
  64. data/test/dummy/app/views/exception_notifier/_new_section.html.erb +1 -0
  65. data/test/dummy/app/views/exception_notifier/_new_section.text.erb +1 -0
  66. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  67. data/test/dummy/app/views/posts/_form.html.erb +0 -0
  68. data/test/dummy/app/views/posts/new.html.erb +0 -0
  69. data/test/dummy/app/views/posts/show.html.erb +0 -0
  70. data/test/dummy/config.ru +4 -0
  71. data/test/dummy/config/application.rb +42 -0
  72. data/test/dummy/config/boot.rb +6 -0
  73. data/test/dummy/config/database.yml +22 -0
  74. data/test/dummy/config/environment.rb +17 -0
  75. data/test/dummy/config/environments/development.rb +25 -0
  76. data/test/dummy/config/environments/production.rb +50 -0
  77. data/test/dummy/config/environments/test.rb +38 -0
  78. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  79. data/test/dummy/config/initializers/inflections.rb +10 -0
  80. data/test/dummy/config/initializers/mime_types.rb +5 -0
  81. data/test/dummy/config/initializers/secret_token.rb +8 -0
  82. data/test/dummy/config/initializers/session_store.rb +8 -0
  83. data/test/dummy/config/locales/en.yml +5 -0
  84. data/test/dummy/config/routes.rb +3 -0
  85. data/test/dummy/db/migrate/20110729022608_create_posts.rb +15 -0
  86. data/test/dummy/db/schema.rb +24 -0
  87. data/test/dummy/db/seeds.rb +7 -0
  88. data/test/dummy/lib/tasks/.gitkeep +0 -0
  89. data/test/dummy/public/404.html +26 -0
  90. data/test/dummy/public/422.html +26 -0
  91. data/test/dummy/public/500.html +26 -0
  92. data/test/dummy/public/favicon.ico +0 -0
  93. data/test/dummy/public/images/rails.png +0 -0
  94. data/test/dummy/public/index.html +239 -0
  95. data/test/dummy/public/javascripts/application.js +2 -0
  96. data/test/dummy/public/javascripts/controls.js +965 -0
  97. data/test/dummy/public/javascripts/dragdrop.js +974 -0
  98. data/test/dummy/public/javascripts/effects.js +1123 -0
  99. data/test/dummy/public/javascripts/prototype.js +6001 -0
  100. data/test/dummy/public/javascripts/rails.js +191 -0
  101. data/test/dummy/public/robots.txt +5 -0
  102. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  103. data/test/dummy/public/stylesheets/scaffold.css +56 -0
  104. data/test/dummy/script/rails +6 -0
  105. data/test/dummy/test/fixtures/posts.yml +11 -0
  106. data/test/dummy/test/functional/posts_controller_test.rb +224 -0
  107. data/test/dummy/test/test_helper.rb +13 -0
  108. data/test/exception_notification/rack_test.rb +20 -0
  109. data/test/exception_notifier/campfire_notifier_test.rb +100 -0
  110. data/test/exception_notifier/email_notifier_test.rb +185 -0
  111. data/test/exception_notifier/hipchat_notifier_test.rb +177 -0
  112. data/test/exception_notifier/irc_notifier_test.rb +121 -0
  113. data/test/exception_notifier/sidekiq_test.rb +27 -0
  114. data/test/exception_notifier/slack_notifier_test.rb +179 -0
  115. data/test/exception_notifier/webhook_notifier_test.rb +68 -0
  116. data/test/exception_notifier_test.rb +103 -0
  117. data/test/test_helper.rb +18 -0
  118. metadata +428 -0
@@ -0,0 +1,121 @@
1
+ require 'test_helper'
2
+ require 'carrier-pigeon'
3
+
4
+ class IrcNotifierTest < ActiveSupport::TestCase
5
+
6
+ test "should send irc notification if properly configured" do
7
+ options = {
8
+ :domain => 'irc.example.com'
9
+ }
10
+
11
+ CarrierPigeon.expects(:send).with(has_key(:uri)) do |v|
12
+ /divided by 0/.match(v[:message])
13
+ end
14
+
15
+ irc = ExceptionNotifier::IrcNotifier.new(options)
16
+ irc.call(fake_exception)
17
+ end
18
+
19
+ test "should call pre/post_callback if specified" do
20
+ pre_callback_called, post_callback_called = 0,0
21
+
22
+ options = {
23
+ :domain => 'irc.example.com',
24
+ :pre_callback => proc { |*| pre_callback_called += 1},
25
+ :post_callback => proc { |*| post_callback_called += 1}
26
+ }
27
+
28
+ CarrierPigeon.expects(:send).with(has_key(:uri)) do |v|
29
+ /divided by 0/.match(v[:message])
30
+ end
31
+
32
+ irc = ExceptionNotifier::IrcNotifier.new(options)
33
+ irc.call(fake_exception)
34
+ assert_equal(1, pre_callback_called)
35
+ assert_equal(1, post_callback_called)
36
+ end
37
+
38
+ test "should send irc notification without backtrace info if properly configured" do
39
+ options = {
40
+ :domain => 'irc.example.com'
41
+ }
42
+
43
+ CarrierPigeon.expects(:send).with(has_key(:uri)) do |v|
44
+ /my custom error/.match(v[:message])
45
+ end
46
+
47
+ irc = ExceptionNotifier::IrcNotifier.new(options)
48
+ irc.call(fake_exception_without_backtrace)
49
+ end
50
+
51
+ test "should properly construct URI from constituent parts" do
52
+ options = {
53
+ :nick => 'BadNewsBot',
54
+ :password => 'secret',
55
+ :domain => 'irc.example.com',
56
+ :port => 9999,
57
+ :channel => '#exceptions'
58
+ }
59
+
60
+ CarrierPigeon.expects(:send).with(has_entry(uri: "irc://BadNewsBot:secret@irc.example.com:9999/#exceptions"))
61
+
62
+ irc = ExceptionNotifier::IrcNotifier.new(options)
63
+ irc.call(fake_exception)
64
+ end
65
+
66
+ test "should properly add recipients if specified" do
67
+ options = {
68
+ domain: 'irc.example.com',
69
+ recipients: ['peter', 'michael', 'samir']
70
+ }
71
+
72
+ CarrierPigeon.expects(:send).with(has_key(:uri)) do |v|
73
+ /peter, michael, samir/.match(v[:message])
74
+ end
75
+
76
+ irc = ExceptionNotifier::IrcNotifier.new(options)
77
+ irc.call(fake_exception)
78
+ end
79
+
80
+ test "should properly set miscellaneous options" do
81
+ options = {
82
+ domain: 'irc.example.com',
83
+ ssl: true,
84
+ join: true,
85
+ notice: true,
86
+ prefix: '[test notification]'
87
+ }
88
+
89
+ CarrierPigeon.expects(:send).with(has_entries(
90
+ ssl: true,
91
+ join: true,
92
+ notice: true,
93
+ )) do |v|
94
+ /\[test notification\]/.match(v[:message])
95
+ end
96
+
97
+ irc = ExceptionNotifier::IrcNotifier.new(options)
98
+ irc.call(fake_exception)
99
+ end
100
+
101
+ test "should not send irc notification if badly configured" do
102
+ wrong_params = { domain: '##scriptkiddie.com###'}
103
+ irc = ExceptionNotifier::IrcNotifier.new(wrong_params)
104
+
105
+ assert_nil irc.call(fake_exception)
106
+ end
107
+
108
+ private
109
+
110
+ def fake_exception
111
+ exception = begin
112
+ 5/0
113
+ rescue Exception => e
114
+ e
115
+ end
116
+ end
117
+
118
+ def fake_exception_without_backtrace
119
+ StandardError.new('my custom error')
120
+ end
121
+ end
@@ -0,0 +1,27 @@
1
+ require "test_helper"
2
+
3
+ # To allow sidekiq error handlers to be registered, sidekiq must be in
4
+ # "server mode". This mode is triggered by loading sidekiq/cli. Note this
5
+ # has to be loaded before exception_notification/sidekiq.
6
+ require "sidekiq/cli"
7
+
8
+ require "exception_notification/sidekiq"
9
+
10
+ class MockSidekiqServer
11
+ include ::Sidekiq::ExceptionHandler
12
+ end
13
+
14
+ class SidekiqTest < ActiveSupport::TestCase
15
+ test "should call notify_exception when sidekiq raises an error" do
16
+ server = MockSidekiqServer.new
17
+ message = Hash.new
18
+ exception = RuntimeError.new
19
+
20
+ ExceptionNotifier.expects(:notify_exception).with(
21
+ exception,
22
+ :data => { :sidekiq => message }
23
+ )
24
+
25
+ server.handle_exception(exception, message)
26
+ end
27
+ end
@@ -0,0 +1,179 @@
1
+ require 'test_helper'
2
+ require 'slack-notifier'
3
+
4
+ class SlackNotifierTest < ActiveSupport::TestCase
5
+
6
+ def setup
7
+ @exception = fake_exception
8
+ @exception.stubs(:backtrace).returns(fake_backtrace)
9
+ @exception.stubs(:message).returns('exception message')
10
+ Socket.stubs(:gethostname).returns('example.com')
11
+ end
12
+
13
+ test "should send a slack notification if properly configured" do
14
+ options = {
15
+ webhook_url: "http://slack.webhook.url"
16
+ }
17
+
18
+ Slack::Notifier.any_instance.expects(:ping).with('', fake_notification)
19
+
20
+ slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
21
+ slack_notifier.call(@exception)
22
+ end
23
+
24
+ test "should send a slack notification without backtrace info if properly configured" do
25
+ options = {
26
+ webhook_url: "http://slack.webhook.url"
27
+ }
28
+
29
+ Slack::Notifier.any_instance.expects(:ping).with('', fake_notification(fake_exception_without_backtrace))
30
+
31
+ slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
32
+ slack_notifier.call(fake_exception_without_backtrace)
33
+ end
34
+
35
+ test "should send the notification to the specified channel" do
36
+ options = {
37
+ webhook_url: "http://slack.webhook.url",
38
+ channel: "channel"
39
+ }
40
+
41
+ Slack::Notifier.any_instance.expects(:ping).with('', fake_notification)
42
+
43
+ slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
44
+ slack_notifier.call(@exception)
45
+
46
+ assert_equal slack_notifier.notifier.channel, options[:channel]
47
+ end
48
+
49
+ test "should send the notification to the specified username" do
50
+ options = {
51
+ webhook_url: "http://slack.webhook.url",
52
+ username: "username"
53
+ }
54
+
55
+ Slack::Notifier.any_instance.expects(:ping).with('', fake_notification)
56
+
57
+ slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
58
+ slack_notifier.call(@exception)
59
+
60
+ assert_equal slack_notifier.notifier.username, options[:username]
61
+ end
62
+
63
+ test "should pass the additional parameters to Slack::Notifier.ping" do
64
+ options = {
65
+ webhook_url: "http://slack.webhook.url",
66
+ username: "test",
67
+ custom_hook: "hook",
68
+ additional_parameters: {
69
+ icon_url: "icon",
70
+ }
71
+ }
72
+
73
+ Slack::Notifier.any_instance.expects(:ping).with('', options[:additional_parameters].merge(fake_notification) )
74
+
75
+ slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
76
+ slack_notifier.call(@exception)
77
+ end
78
+
79
+ test "shouldn't send a slack notification if webhook url is missing" do
80
+ options = {}
81
+
82
+ slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
83
+
84
+ assert_nil slack_notifier.notifier
85
+ assert_nil slack_notifier.call(@exception)
86
+ end
87
+
88
+ test "should pass along environment data" do
89
+ options = {
90
+ webhook_url: "http://slack.webhook.url",
91
+ ignore_data_if: lambda {|k,v|
92
+ "#{k}" == 'key_to_be_ignored' || v.is_a?(Hash)
93
+ }
94
+ }
95
+
96
+ notification_options = {
97
+ env: {
98
+ 'exception_notifier.exception_data' => {foo: 'bar', john: 'doe'}
99
+ },
100
+ data: {
101
+ 'user_id' => 5,
102
+ 'key_to_be_ignored' => 'whatever',
103
+ 'ignore_as_well' => {what: 'ever'}
104
+ }
105
+ }
106
+
107
+ expected_data_string = "foo: bar\njohn: doe\nuser_id: 5"
108
+
109
+ Slack::Notifier.any_instance.expects(:ping).with('', fake_notification(@exception, expected_data_string))
110
+ slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
111
+ slack_notifier.call(@exception, notification_options)
112
+ end
113
+
114
+ test "should call pre/post_callback proc if specified" do
115
+ post_callback_called = 0
116
+ options = {
117
+ webhook_url: "http://slack.webhook.url",
118
+ username: "test",
119
+ custom_hook: "hook",
120
+ :pre_callback => proc { |opts, notifier, backtrace, message, message_opts|
121
+ (message_opts[:attachments] = []) << { text: "#{backtrace.join("\n")}", color: 'danger' }
122
+ },
123
+ :post_callback => proc { |opts, notifier, backtrace, message, message_opts|
124
+ post_callback_called = 1
125
+ },
126
+ additional_parameters: {
127
+ icon_url: "icon",
128
+ }
129
+ }
130
+
131
+ Slack::Notifier.any_instance.expects(:ping).with('',
132
+ {:icon_url => 'icon',
133
+ :attachments => [
134
+ {:text => fake_backtrace.join("\n"),
135
+ :color => 'danger'}
136
+ ]})
137
+
138
+ slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
139
+ slack_notifier.call(@exception)
140
+ assert_equal(post_callback_called, 1)
141
+ end
142
+
143
+ private
144
+
145
+ def fake_exception
146
+ begin
147
+ 5/0
148
+ rescue Exception => e
149
+ e
150
+ end
151
+ end
152
+
153
+ def fake_exception_without_backtrace
154
+ StandardError.new('my custom error')
155
+ end
156
+
157
+ def fake_backtrace
158
+ [
159
+ "backtrace line 1",
160
+ "backtrace line 2",
161
+ "backtrace line 3",
162
+ "backtrace line 4",
163
+ "backtrace line 5",
164
+ "backtrace line 6",
165
+ ]
166
+ end
167
+
168
+ def fake_notification(exception = @exception, data_string = nil)
169
+ text = "*An exception occurred while doing*: ` <>`\n"
170
+
171
+ fields = [ { title: 'Exception', value: exception.message} ]
172
+ fields.push({ title: 'Hostname', value: 'example.com' })
173
+ fields.push({ title: 'Backtrace', value: "```#{fake_backtrace.join("\n")}```" }) if exception.backtrace
174
+ fields.push({ title: 'Data', value: "```#{data_string}```" }) if data_string
175
+
176
+ { attachments: [ color: 'danger', text: text, fields: fields, mrkdwn_in: %w(text fields) ] }
177
+ end
178
+
179
+ end
@@ -0,0 +1,68 @@
1
+ require 'test_helper'
2
+ require 'httparty'
3
+
4
+ class WebhookNotifierTest < ActiveSupport::TestCase
5
+
6
+ test "should send webhook notification if properly configured" do
7
+ ExceptionNotifier::WebhookNotifier.stubs(:new).returns(Object.new)
8
+ webhook = ExceptionNotifier::WebhookNotifier.new({:url => 'http://localhost:8000'})
9
+ webhook.stubs(:call).returns(fake_response)
10
+ response = webhook.call(fake_exception)
11
+
12
+ refute_nil response
13
+ assert_equal response[:status], 200
14
+ assert_equal response[:body][:exception][:error_class], "ZeroDivisionError"
15
+ assert_includes response[:body][:exception][:message], "divided by 0"
16
+ assert_includes response[:body][:exception][:backtrace], "/exception_notification/test/webhook_notifier_test.rb:48"
17
+
18
+ assert response[:body][:request][:cookies].has_key?(:cookie_item1)
19
+ assert_equal response[:body][:request][:url], "http://example.com/example"
20
+ assert_equal response[:body][:request][:ip_address], "192.168.1.1"
21
+ assert response[:body][:request][:environment].has_key?(:env_item1)
22
+ assert_equal response[:body][:request][:controller], "#<ControllerName:0x007f9642a04d00>"
23
+ assert response[:body][:request][:session].has_key?(:session_item1)
24
+ assert response[:body][:request][:parameters].has_key?(:controller)
25
+ assert response[:body][:data][:extra_data].has_key?(:data_item1)
26
+ end
27
+
28
+ test "should call pre/post_callback if specified" do
29
+ HTTParty.stubs(:send).returns(fake_response)
30
+ webhook = ExceptionNotifier::WebhookNotifier.new({:url => 'http://localhost:8000'})
31
+ webhook.call(fake_exception)
32
+ end
33
+
34
+ private
35
+
36
+ def fake_response
37
+ {
38
+ :status => 200,
39
+ :body => {
40
+ :exception => {
41
+ :error_class => 'ZeroDivisionError',
42
+ :message => 'divided by 0',
43
+ :backtrace => '/exception_notification/test/webhook_notifier_test.rb:48:in `/'
44
+ },
45
+ :data => {
46
+ :extra_data => {:data_item1 => "datavalue1", :data_item2 => "datavalue2"}
47
+ },
48
+ :request => {
49
+ :cookies => {:cookie_item1 => 'cookieitemvalue1', :cookie_item2 => 'cookieitemvalue2'},
50
+ :url => 'http://example.com/example',
51
+ :ip_address => '192.168.1.1',
52
+ :environment => {:env_item1 => "envitem1", :env_item2 => "envitem2"},
53
+ :controller => '#<ControllerName:0x007f9642a04d00>',
54
+ :session => {:session_item1 => "sessionitem1", :session_item2 => "sessionitem2"},
55
+ :parameters => {:action =>"index", :controller =>"projects"}
56
+ }
57
+ }
58
+ }
59
+ end
60
+
61
+ def fake_exception
62
+ exception = begin
63
+ 5/0
64
+ rescue Exception => e
65
+ e
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,103 @@
1
+ require 'test_helper'
2
+
3
+ class ExceptionNotifierTest < ActiveSupport::TestCase
4
+ test "should have default ignored exceptions" do
5
+ assert_equal ExceptionNotifier.ignored_exceptions, ['ActiveRecord::RecordNotFound', 'AbstractController::ActionNotFound', 'ActionController::RoutingError', 'ActionController::UnknownFormat']
6
+ end
7
+
8
+ test "should have email notifier registered" do
9
+ assert_equal ExceptionNotifier.notifiers, [:email]
10
+ end
11
+
12
+ test "should have a valid email notifier" do
13
+ @email_notifier = ExceptionNotifier.registered_exception_notifier(:email)
14
+ refute_nil @email_notifier
15
+ assert_equal @email_notifier.class, ExceptionNotifier::EmailNotifier
16
+ assert_respond_to @email_notifier, :call
17
+ end
18
+
19
+ test "should allow register/unregister another notifier" do
20
+ called = false
21
+ proc_notifier = lambda { |exception, options| called = true }
22
+ ExceptionNotifier.register_exception_notifier(:proc, proc_notifier)
23
+
24
+ assert_equal ExceptionNotifier.notifiers.sort, [:email, :proc]
25
+
26
+ exception = StandardError.new
27
+
28
+ ExceptionNotifier.notify_exception(exception)
29
+ assert called
30
+
31
+ ExceptionNotifier.unregister_exception_notifier(:proc)
32
+ assert_equal ExceptionNotifier.notifiers, [:email]
33
+ end
34
+
35
+ test "should allow select notifiers to send error to" do
36
+ notifier1_calls = 0
37
+ notifier1 = lambda { |exception, options| notifier1_calls += 1 }
38
+ ExceptionNotifier.register_exception_notifier(:notifier1, notifier1)
39
+
40
+ notifier2_calls = 0
41
+ notifier2 = lambda { |exception, options| notifier2_calls += 1 }
42
+ ExceptionNotifier.register_exception_notifier(:notifier2, notifier2)
43
+
44
+ assert_equal ExceptionNotifier.notifiers.sort, [:email, :notifier1, :notifier2]
45
+
46
+ exception = StandardError.new
47
+ ExceptionNotifier.notify_exception(exception)
48
+ assert_equal notifier1_calls, 1
49
+ assert_equal notifier2_calls, 1
50
+
51
+ ExceptionNotifier.notify_exception(exception, {:notifiers => :notifier1})
52
+ assert_equal notifier1_calls, 2
53
+ assert_equal notifier2_calls, 1
54
+
55
+ ExceptionNotifier.notify_exception(exception, {:notifiers => :notifier2})
56
+ assert_equal notifier1_calls, 2
57
+ assert_equal notifier2_calls, 2
58
+
59
+ ExceptionNotifier.unregister_exception_notifier(:notifier1)
60
+ ExceptionNotifier.unregister_exception_notifier(:notifier2)
61
+ assert_equal ExceptionNotifier.notifiers, [:email]
62
+ end
63
+
64
+ test "should ignore exception if satisfies conditional ignore" do
65
+ env = "production"
66
+ ExceptionNotifier.ignore_if do |exception, options|
67
+ env != "production"
68
+ end
69
+
70
+ notifier_calls = 0
71
+ test_notifier = lambda { |exception, options| notifier_calls += 1 }
72
+ ExceptionNotifier.register_exception_notifier(:test, test_notifier)
73
+
74
+ exception = StandardError.new
75
+
76
+ ExceptionNotifier.notify_exception(exception, {:notifiers => :test})
77
+ assert_equal notifier_calls, 1
78
+
79
+ env = "development"
80
+ ExceptionNotifier.notify_exception(exception, {:notifiers => :test})
81
+ assert_equal notifier_calls, 1
82
+
83
+ ExceptionNotifier.clear_ignore_conditions!
84
+ ExceptionNotifier.unregister_exception_notifier(:test)
85
+ end
86
+
87
+ test "should not send notification if one of ignored exceptions" do
88
+ notifier_calls = 0
89
+ test_notifier = lambda { |exception, options| notifier_calls += 1 }
90
+ ExceptionNotifier.register_exception_notifier(:test, test_notifier)
91
+
92
+ exception = StandardError.new
93
+
94
+ ExceptionNotifier.notify_exception(exception, {:notifiers => :test})
95
+ assert_equal notifier_calls, 1
96
+
97
+ ExceptionNotifier.notify_exception(exception, {:notifiers => :test, :ignore_exceptions => 'StandardError' })
98
+ assert_equal notifier_calls, 1
99
+
100
+ ExceptionNotifier.unregister_exception_notifier(:test)
101
+ end
102
+
103
+ end