exception_notification 4.6.0 → 5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.rdoc +16 -0
- data/CONTRIBUTING.md +23 -51
- data/Gemfile +1 -1
- data/Gemfile.lock +27 -33
- data/README.md +65 -31
- data/Rakefile +14 -7
- data/exception_notification.gemspec +27 -30
- data/gemfiles/pinned_dependencies.gemfile +8 -0
- data/gemfiles/rails7_1.gemfile +5 -0
- data/gemfiles/rails7_2.gemfile +5 -0
- data/gemfiles/rails8_0.gemfile +5 -0
- data/lib/exception_notification/rack.rb +4 -4
- data/lib/exception_notification/rails.rb +2 -2
- data/lib/exception_notification/rake.rb +3 -7
- data/lib/exception_notification/resque.rb +2 -2
- data/lib/exception_notification/sidekiq.rb +8 -23
- data/lib/exception_notification/version.rb +1 -1
- data/lib/exception_notification.rb +3 -3
- data/lib/exception_notifier/datadog_notifier.rb +26 -26
- data/lib/exception_notifier/email_notifier.rb +34 -30
- data/lib/exception_notifier/google_chat_notifier.rb +9 -9
- data/lib/exception_notifier/hipchat_notifier.rb +12 -12
- data/lib/exception_notifier/irc_notifier.rb +6 -6
- data/lib/exception_notifier/mattermost_notifier.rb +13 -13
- data/lib/exception_notifier/modules/error_grouping.rb +5 -5
- data/lib/exception_notifier/modules/formatter.rb +12 -12
- data/lib/exception_notifier/notifier.rb +3 -3
- data/lib/exception_notifier/slack_notifier.rb +16 -16
- data/lib/exception_notifier/sns_notifier.rb +9 -9
- data/lib/exception_notifier/teams_notifier.rb +61 -57
- data/lib/exception_notifier/webhook_notifier.rb +3 -3
- data/lib/exception_notifier.rb +27 -26
- data/lib/generators/exception_notification/install_generator.rb +7 -7
- data/lib/generators/exception_notification/templates/exception_notification.rb.erb +26 -27
- data/test/exception_notification/rack_test.rb +14 -14
- data/test/exception_notification/rake_test.rb +13 -13
- data/test/exception_notification/resque_test.rb +14 -14
- data/test/exception_notifier/datadog_notifier_test.rb +47 -46
- data/test/exception_notifier/email_notifier_test.rb +89 -98
- data/test/exception_notifier/google_chat_notifier_test.rb +77 -77
- data/test/exception_notifier/hipchat_notifier_test.rb +76 -74
- data/test/exception_notifier/irc_notifier_test.rb +26 -26
- data/test/exception_notifier/mattermost_notifier_test.rb +77 -77
- data/test/exception_notifier/modules/error_grouping_test.rb +39 -39
- data/test/exception_notifier/modules/formatter_test.rb +51 -49
- data/test/exception_notifier/sidekiq_test.rb +17 -10
- data/test/exception_notifier/slack_notifier_test.rb +66 -67
- data/test/exception_notifier/sns_notifier_test.rb +73 -70
- data/test/exception_notifier/teams_notifier_test.rb +33 -33
- data/test/exception_notifier/webhook_notifier_test.rb +34 -34
- data/test/exception_notifier_test.rb +51 -41
- data/test/test_helper.rb +8 -11
- metadata +45 -85
- data/Appraisals +0 -9
- data/gemfiles/rails5_2.gemfile +0 -7
- data/gemfiles/rails6_0.gemfile +0 -7
- data/gemfiles/rails6_1.gemfile +0 -7
- data/gemfiles/rails7_0.gemfile +0 -7
@@ -1,37 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "test_helper"
|
4
|
+
require "rack"
|
5
|
+
require "hipchat"
|
6
6
|
|
7
7
|
class HipchatNotifierTest < ActiveSupport::TestCase
|
8
|
-
test
|
8
|
+
test "should send hipchat notification if properly configured" do
|
9
9
|
options = {
|
10
|
-
api_token:
|
11
|
-
room_name:
|
12
|
-
color:
|
10
|
+
api_token: "good_token",
|
11
|
+
room_name: "room_name",
|
12
|
+
color: "yellow"
|
13
13
|
}
|
14
14
|
|
15
|
-
HipChat::Room.any_instance.expects(:send).with(
|
15
|
+
HipChat::Room.any_instance.expects(:send).with("Exception", fake_body, {color: "yellow"})
|
16
16
|
|
17
17
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
18
18
|
hipchat.call(fake_exception)
|
19
19
|
end
|
20
20
|
|
21
|
-
test
|
21
|
+
test "should call pre/post_callback if specified" do
|
22
22
|
pre_callback_called = 0
|
23
23
|
post_callback_called = 0
|
24
24
|
options = {
|
25
|
-
api_token:
|
26
|
-
room_name:
|
27
|
-
color:
|
25
|
+
api_token: "good_token",
|
26
|
+
room_name: "room_name",
|
27
|
+
color: "yellow",
|
28
28
|
pre_callback: proc { |*| pre_callback_called += 1 },
|
29
29
|
post_callback: proc { |*| post_callback_called += 1 }
|
30
30
|
}
|
31
31
|
|
32
32
|
HipChat::Room.any_instance
|
33
|
-
|
34
|
-
|
33
|
+
.expects(:send)
|
34
|
+
.with("Exception", fake_body, {color: "yellow"}.merge(options.except(:api_token, :room_name)))
|
35
35
|
|
36
36
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
37
37
|
hipchat.call(fake_exception)
|
@@ -39,152 +39,154 @@ class HipchatNotifierTest < ActiveSupport::TestCase
|
|
39
39
|
assert_equal(1, post_callback_called)
|
40
40
|
end
|
41
41
|
|
42
|
-
test
|
42
|
+
test "should send hipchat notification without backtrace info if properly configured" do
|
43
43
|
options = {
|
44
|
-
api_token:
|
45
|
-
room_name:
|
46
|
-
color:
|
44
|
+
api_token: "good_token",
|
45
|
+
room_name: "room_name",
|
46
|
+
color: "yellow"
|
47
47
|
}
|
48
48
|
|
49
|
-
HipChat::Room.any_instance.expects(:send).with(
|
49
|
+
HipChat::Room.any_instance.expects(:send).with("Exception", fake_body_without_backtrace, {color: "yellow"})
|
50
50
|
|
51
51
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
52
52
|
hipchat.call(fake_exception_without_backtrace)
|
53
53
|
end
|
54
54
|
|
55
|
-
test
|
55
|
+
test "should allow custom from value if set" do
|
56
56
|
options = {
|
57
|
-
api_token:
|
58
|
-
room_name:
|
59
|
-
from:
|
57
|
+
api_token: "good_token",
|
58
|
+
room_name: "room_name",
|
59
|
+
from: "TrollFace"
|
60
60
|
}
|
61
61
|
|
62
|
-
HipChat::Room.any_instance.expects(:send).with(
|
62
|
+
HipChat::Room.any_instance.expects(:send).with("TrollFace", fake_body, {color: "red"})
|
63
63
|
|
64
64
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
65
65
|
hipchat.call(fake_exception)
|
66
66
|
end
|
67
67
|
|
68
|
-
test
|
68
|
+
test "should not send hipchat notification if badly configured" do
|
69
69
|
wrong_params = {
|
70
|
-
api_token:
|
71
|
-
room_name:
|
70
|
+
api_token: "bad_token",
|
71
|
+
room_name: "test_room"
|
72
72
|
}
|
73
73
|
|
74
|
-
HipChat::Client.stubs(:new).with(
|
74
|
+
HipChat::Client.stubs(:new).with("bad_token", {api_version: "v1"}).returns(nil)
|
75
75
|
|
76
76
|
hipchat = ExceptionNotifier::HipchatNotifier.new(wrong_params)
|
77
77
|
assert_nil hipchat.room
|
78
78
|
end
|
79
79
|
|
80
|
-
test
|
81
|
-
wrong_params = {
|
80
|
+
test "should not send hipchat notification if api_key is missing" do
|
81
|
+
wrong_params = {room_name: "test_room"}
|
82
82
|
|
83
|
-
HipChat::Client.stubs(:new).with(nil, api_version:
|
83
|
+
HipChat::Client.stubs(:new).with(nil, {api_version: "v1"}).returns(nil)
|
84
84
|
|
85
85
|
hipchat = ExceptionNotifier::HipchatNotifier.new(wrong_params)
|
86
86
|
assert_nil hipchat.room
|
87
87
|
end
|
88
88
|
|
89
|
-
test
|
90
|
-
wrong_params = {
|
89
|
+
test "should not send hipchat notification if room_name is missing" do
|
90
|
+
wrong_params = {api_token: "good_token"}
|
91
91
|
|
92
|
-
HipChat::Client.stubs(:new).with(
|
92
|
+
HipChat::Client.stubs(:new).with("good_token", {api_version: "v1"}).returns({})
|
93
93
|
|
94
94
|
hipchat = ExceptionNotifier::HipchatNotifier.new(wrong_params)
|
95
95
|
assert_nil hipchat.room
|
96
96
|
end
|
97
97
|
|
98
|
-
test
|
98
|
+
test "should send hipchat notification with message_template" do
|
99
99
|
options = {
|
100
|
-
api_token:
|
101
|
-
room_name:
|
102
|
-
color:
|
100
|
+
api_token: "good_token",
|
101
|
+
room_name: "room_name",
|
102
|
+
color: "yellow",
|
103
103
|
message_template: ->(exception, _) { "This is custom message: '#{exception.message}'" }
|
104
104
|
}
|
105
105
|
|
106
106
|
HipChat::Room.any_instance
|
107
|
-
|
108
|
-
|
107
|
+
.expects(:send)
|
108
|
+
.with("Exception", "This is custom message: '#{fake_exception.message}'", {color: "yellow"})
|
109
109
|
|
110
110
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
111
111
|
hipchat.call(fake_exception)
|
112
112
|
end
|
113
113
|
|
114
|
-
test
|
114
|
+
test "should send hipchat notification exclude accumulated errors count" do
|
115
115
|
options = {
|
116
|
-
api_token:
|
117
|
-
room_name:
|
118
|
-
color:
|
116
|
+
api_token: "good_token",
|
117
|
+
room_name: "room_name",
|
118
|
+
color: "yellow"
|
119
119
|
}
|
120
120
|
|
121
|
-
HipChat::Room.any_instance.expects(:send).with { |_, msg, _| msg.start_with?(
|
121
|
+
HipChat::Room.any_instance.expects(:send).with { |_, msg, _| msg.start_with?("A new exception occurred:") }
|
122
122
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
123
123
|
hipchat.call(fake_exception)
|
124
124
|
end
|
125
125
|
|
126
|
-
test
|
126
|
+
test "should send hipchat notification include accumulated errors count" do
|
127
127
|
options = {
|
128
|
-
api_token:
|
129
|
-
room_name:
|
130
|
-
color:
|
128
|
+
api_token: "good_token",
|
129
|
+
room_name: "room_name",
|
130
|
+
color: "yellow"
|
131
131
|
}
|
132
132
|
|
133
|
-
HipChat::Room.any_instance.expects(:send).with { |_, msg, _| msg.start_with?(
|
133
|
+
HipChat::Room.any_instance.expects(:send).with { |_, msg, _| msg.start_with?("The exception occurred 3 times:") }
|
134
134
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
135
135
|
hipchat.call(fake_exception, accumulated_errors_count: 3)
|
136
136
|
end
|
137
137
|
|
138
|
-
test
|
138
|
+
test "should send hipchat notification with HTML-escaped meessage if using default message_template" do
|
139
139
|
options = {
|
140
|
-
api_token:
|
141
|
-
room_name:
|
142
|
-
color:
|
140
|
+
api_token: "good_token",
|
141
|
+
room_name: "room_name",
|
142
|
+
color: "yellow"
|
143
143
|
}
|
144
144
|
|
145
145
|
exception = fake_exception_with_html_characters
|
146
146
|
body = "A new exception occurred: '#{Rack::Utils.escape_html(exception.message)}' on '#{exception.backtrace.first}'"
|
147
147
|
|
148
|
-
HipChat::Room.any_instance.expects(:send).with(
|
148
|
+
HipChat::Room.any_instance.expects(:send).with("Exception", body, {color: "yellow"})
|
149
149
|
|
150
150
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
151
151
|
hipchat.call(exception)
|
152
152
|
end
|
153
153
|
|
154
|
-
test
|
154
|
+
test "should use APIv1 if api_version is not specified" do
|
155
155
|
options = {
|
156
|
-
api_token:
|
157
|
-
room_name:
|
156
|
+
api_token: "good_token",
|
157
|
+
room_name: "room_name"
|
158
158
|
}
|
159
159
|
|
160
|
-
HipChat::Client.
|
160
|
+
HipChat::Client.expects(:new).with("good_token", {api_version: "v1"}).returns({})
|
161
161
|
|
162
162
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
163
163
|
hipchat.call(fake_exception)
|
164
164
|
end
|
165
165
|
|
166
|
-
test
|
166
|
+
test "should use APIv2 when specified" do
|
167
167
|
options = {
|
168
|
-
api_token:
|
169
|
-
room_name:
|
170
|
-
api_version:
|
168
|
+
api_token: "good_token",
|
169
|
+
room_name: "room_name",
|
170
|
+
api_version: "v2"
|
171
171
|
}
|
172
172
|
|
173
|
-
HipChat::Client.
|
173
|
+
HipChat::Client.expects(:new).with("good_token", {api_version: "v2"}).returns({})
|
174
174
|
|
175
175
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
176
176
|
hipchat.call(fake_exception)
|
177
177
|
end
|
178
178
|
|
179
|
-
test
|
179
|
+
test "should allow server_url value (for a self-hosted HipChat Server) if set" do
|
180
180
|
options = {
|
181
|
-
api_token:
|
182
|
-
room_name:
|
183
|
-
api_version:
|
184
|
-
server_url:
|
181
|
+
api_token: "good_token",
|
182
|
+
room_name: "room_name",
|
183
|
+
api_version: "v2",
|
184
|
+
server_url: "https://domain.com"
|
185
185
|
}
|
186
186
|
|
187
|
-
HipChat::Client.
|
187
|
+
HipChat::Client.expects(:new)
|
188
|
+
.with("good_token", {api_version: "v2", server_url: "https://domain.com"})
|
189
|
+
.returns({})
|
188
190
|
|
189
191
|
hipchat = ExceptionNotifier::HipchatNotifier.new(options)
|
190
192
|
hipchat.call(fake_exception)
|
@@ -198,13 +200,13 @@ class HipchatNotifierTest < ActiveSupport::TestCase
|
|
198
200
|
|
199
201
|
def fake_exception
|
200
202
|
5 / 0
|
201
|
-
rescue
|
203
|
+
rescue => e
|
202
204
|
e
|
203
205
|
end
|
204
206
|
|
205
207
|
def fake_exception_with_html_characters
|
206
|
-
raise StandardError,
|
207
|
-
rescue
|
208
|
+
raise StandardError, "an error with <html> characters"
|
209
|
+
rescue => e
|
208
210
|
e
|
209
211
|
end
|
210
212
|
|
@@ -213,6 +215,6 @@ class HipchatNotifierTest < ActiveSupport::TestCase
|
|
213
215
|
end
|
214
216
|
|
215
217
|
def fake_exception_without_backtrace
|
216
|
-
StandardError.new(
|
218
|
+
StandardError.new("my custom error")
|
217
219
|
end
|
218
220
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "test_helper"
|
4
|
+
require "carrier-pigeon"
|
5
5
|
|
6
6
|
class IrcNotifierTest < ActiveSupport::TestCase
|
7
|
-
test
|
7
|
+
test "should send irc notification if properly configured" do
|
8
8
|
options = {
|
9
|
-
domain:
|
9
|
+
domain: "irc.example.com"
|
10
10
|
}
|
11
11
|
|
12
12
|
CarrierPigeon.expects(:send).with(has_key(:uri)) do |v|
|
@@ -17,15 +17,15 @@ class IrcNotifierTest < ActiveSupport::TestCase
|
|
17
17
|
irc.call(fake_exception)
|
18
18
|
end
|
19
19
|
|
20
|
-
test
|
20
|
+
test "should exclude errors count in message if :accumulated_errors_count nil" do
|
21
21
|
irc = ExceptionNotifier::IrcNotifier.new({})
|
22
22
|
irc.stubs(:active?).returns(true)
|
23
23
|
|
24
|
-
irc.expects(:send_message).with { |message| message.include?(
|
24
|
+
irc.expects(:send_message).with { |message| message.include?("divided by 0") }.once
|
25
25
|
irc.call(fake_exception)
|
26
26
|
end
|
27
27
|
|
28
|
-
test
|
28
|
+
test "should include errors count in message if :accumulated_errors_count is 3" do
|
29
29
|
irc = ExceptionNotifier::IrcNotifier.new({})
|
30
30
|
irc.stubs(:active?).returns(true)
|
31
31
|
|
@@ -33,12 +33,12 @@ class IrcNotifierTest < ActiveSupport::TestCase
|
|
33
33
|
irc.call(fake_exception, accumulated_errors_count: 3)
|
34
34
|
end
|
35
35
|
|
36
|
-
test
|
36
|
+
test "should call pre/post_callback if specified" do
|
37
37
|
pre_callback_called = 0
|
38
38
|
post_callback_called = 0
|
39
39
|
|
40
40
|
options = {
|
41
|
-
domain:
|
41
|
+
domain: "irc.example.com",
|
42
42
|
pre_callback: proc { |*| pre_callback_called += 1 },
|
43
43
|
post_callback: proc { |*| post_callback_called += 1 }
|
44
44
|
}
|
@@ -53,9 +53,9 @@ class IrcNotifierTest < ActiveSupport::TestCase
|
|
53
53
|
assert_equal(1, post_callback_called)
|
54
54
|
end
|
55
55
|
|
56
|
-
test
|
56
|
+
test "should send irc notification without backtrace info if properly configured" do
|
57
57
|
options = {
|
58
|
-
domain:
|
58
|
+
domain: "irc.example.com"
|
59
59
|
}
|
60
60
|
|
61
61
|
CarrierPigeon.expects(:send).with(has_key(:uri)) do |v|
|
@@ -66,24 +66,24 @@ class IrcNotifierTest < ActiveSupport::TestCase
|
|
66
66
|
irc.call(fake_exception_without_backtrace)
|
67
67
|
end
|
68
68
|
|
69
|
-
test
|
69
|
+
test "should properly construct URI from constituent parts" do
|
70
70
|
options = {
|
71
|
-
nick:
|
72
|
-
password:
|
73
|
-
domain:
|
71
|
+
nick: "BadNewsBot",
|
72
|
+
password: "secret",
|
73
|
+
domain: "irc.example.com",
|
74
74
|
port: 9999,
|
75
|
-
channel:
|
75
|
+
channel: "#exceptions"
|
76
76
|
}
|
77
77
|
|
78
|
-
CarrierPigeon.expects(:send).with(has_entry(uri:
|
78
|
+
CarrierPigeon.expects(:send).with(has_entry(uri: "irc://BadNewsBot:secret@irc.example.com:9999/#exceptions"))
|
79
79
|
|
80
80
|
irc = ExceptionNotifier::IrcNotifier.new(options)
|
81
81
|
irc.call(fake_exception)
|
82
82
|
end
|
83
83
|
|
84
|
-
test
|
84
|
+
test "should properly add recipients if specified" do
|
85
85
|
options = {
|
86
|
-
domain:
|
86
|
+
domain: "irc.example.com",
|
87
87
|
recipients: %w[peter michael samir]
|
88
88
|
}
|
89
89
|
|
@@ -95,13 +95,13 @@ class IrcNotifierTest < ActiveSupport::TestCase
|
|
95
95
|
irc.call(fake_exception)
|
96
96
|
end
|
97
97
|
|
98
|
-
test
|
98
|
+
test "should properly set miscellaneous options" do
|
99
99
|
options = {
|
100
|
-
domain:
|
100
|
+
domain: "irc.example.com",
|
101
101
|
ssl: true,
|
102
102
|
join: true,
|
103
103
|
notice: true,
|
104
|
-
prefix:
|
104
|
+
prefix: "[test notification]"
|
105
105
|
}
|
106
106
|
|
107
107
|
entries = {
|
@@ -118,8 +118,8 @@ class IrcNotifierTest < ActiveSupport::TestCase
|
|
118
118
|
irc.call(fake_exception)
|
119
119
|
end
|
120
120
|
|
121
|
-
test
|
122
|
-
wrong_params = {
|
121
|
+
test "should not send irc notification if badly configured" do
|
122
|
+
wrong_params = {domain: "##scriptkiddie.com###"}
|
123
123
|
irc = ExceptionNotifier::IrcNotifier.new(wrong_params)
|
124
124
|
|
125
125
|
assert_nil irc.call(fake_exception)
|
@@ -129,11 +129,11 @@ class IrcNotifierTest < ActiveSupport::TestCase
|
|
129
129
|
|
130
130
|
def fake_exception
|
131
131
|
5 / 0
|
132
|
-
rescue
|
132
|
+
rescue => e
|
133
133
|
e
|
134
134
|
end
|
135
135
|
|
136
136
|
def fake_exception_without_backtrace
|
137
|
-
StandardError.new(
|
137
|
+
StandardError.new("my custom error")
|
138
138
|
end
|
139
139
|
end
|