exception_notification 4.2.0 → 4.2.1
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 +10 -0
- data/README.md +5 -13
- data/exception_notification.gemspec +2 -2
- data/lib/exception_notification/rack.rb +6 -6
- data/lib/exception_notifier.rb +1 -1
- data/lib/exception_notifier/slack_notifier.rb +17 -5
- data/lib/exception_notifier/webhook_notifier.rb +2 -2
- data/lib/generators/exception_notification/templates/exception_notification.rb +1 -1
- data/test/dummy/config/boot.rb +1 -1
- data/test/dummy/config/environments/test.rb +0 -3
- data/test/exception_notifier/campfire_notifier_test.rb +8 -2
- data/test/exception_notifier/email_notifier_test.rb +2 -2
- data/test/exception_notifier/hipchat_notifier_test.rb +9 -3
- data/test/exception_notifier/irc_notifier_test.rb +1 -1
- data/test/exception_notifier/sidekiq_test.rb +11 -0
- data/test/exception_notifier/slack_notifier_test.rb +32 -4
- data/test/exception_notifier/webhook_notifier_test.rb +28 -2
- data/test/exception_notifier_test.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6de21b765af1465df6205f174cbab7e10b403048
|
4
|
+
data.tar.gz: cade5525679b528aded7b1ad6369e97f40b58947
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe4b7770171a25a7e131d97c922e5c518531f71add293ce42359eb9f2fc84ea7330f2f935657cbf4dc13fa4a8ba2d3d492397469555d665d12d36c52603a82fd
|
7
|
+
data.tar.gz: 92774d00ec26d97246ca9d4e6334f3aac06f04c5242a555eb3a5bd5addfd8a8485bdd72787b0d304146c50e79a7ff4500aaf2a08aca744be963f3a779221b193
|
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 4.2.1
|
2
|
+
|
3
|
+
* enhancements
|
4
|
+
* Allow customizable backtrace for Slack (by @aried3r)
|
5
|
+
* Add `Mongoid::Errors::DocumentNotFound` to ignored_exceptions (by @nazarok)
|
6
|
+
* Improved text in Slack notifier (by @vojtad)
|
7
|
+
|
8
|
+
* bug fixes
|
9
|
+
* Fix data being sent on webhook notifier
|
10
|
+
|
1
11
|
== 4.2.0
|
2
12
|
|
3
13
|
* enhancements
|
data/README.md
CHANGED
@@ -823,7 +823,7 @@ You can choose to ignore certain exceptions, which will make ExceptionNotificati
|
|
823
823
|
|
824
824
|
### :ignore_exceptions
|
825
825
|
|
826
|
-
*Array of strings, default: %w{ActiveRecord::RecordNotFound AbstractController::ActionNotFound ActionController::RoutingError ActionController::UnknownFormat}*
|
826
|
+
*Array of strings, default: %w{ActiveRecord::RecordNotFound Mongoid::Errors::DocumentNotFound AbstractController::ActionNotFound ActionController::RoutingError ActionController::UnknownFormat}*
|
827
827
|
|
828
828
|
Ignore specified exception types. To achieve that, you should use the `:ignore_exceptions` option, like this:
|
829
829
|
|
@@ -950,21 +950,13 @@ As above, make sure the gem is not listed solely under the `production` group, s
|
|
950
950
|
|
951
951
|
## Versions
|
952
952
|
|
953
|
-
For v4.
|
953
|
+
For v4.2.1, see this tag:
|
954
954
|
|
955
|
-
http://github.com/smartinez87/exception_notification/tree/v4.
|
955
|
+
http://github.com/smartinez87/exception_notification/tree/v4.2.1
|
956
956
|
|
957
|
-
For v4.
|
957
|
+
For v4.2.0, see this tag:
|
958
958
|
|
959
|
-
http://github.com/smartinez87/exception_notification/tree/v4.
|
960
|
-
|
961
|
-
For v3.0.1, see this tag:
|
962
|
-
|
963
|
-
http://github.com/smartinez87/exception_notification/tree/v3.0.1
|
964
|
-
|
965
|
-
For v3.0.0, see this tag:
|
966
|
-
|
967
|
-
http://github.com/smartinez87/exception_notification/tree/v3.0.0
|
959
|
+
http://github.com/smartinez87/exception_notification/tree/v4.2.0
|
968
960
|
|
969
961
|
For previous releases, visit:
|
970
962
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'exception_notification'
|
3
|
-
s.version = '4.2.
|
3
|
+
s.version = '4.2.1'
|
4
4
|
s.authors = ["Jamis Buck", "Josh Peek"]
|
5
|
-
s.date = %q{2016-07-
|
5
|
+
s.date = %q{2016-07-17}
|
6
6
|
s.summary = "Exception notification for Rails apps"
|
7
7
|
s.homepage = "https://smartinez87.github.io/exception_notification/"
|
8
8
|
s.email = "smartinez87@gmail.com"
|
@@ -9,22 +9,22 @@ module ExceptionNotification
|
|
9
9
|
|
10
10
|
if options.key?(:ignore_if)
|
11
11
|
rack_ignore = options.delete(:ignore_if)
|
12
|
-
ExceptionNotifier.ignore_if do |exception,
|
13
|
-
|
12
|
+
ExceptionNotifier.ignore_if do |exception, opts|
|
13
|
+
opts.key?(:env) && rack_ignore.call(opts[:env], exception)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
if options.key?(:ignore_crawlers)
|
18
18
|
ignore_crawlers = options.delete(:ignore_crawlers)
|
19
|
-
ExceptionNotifier.ignore_if do |exception,
|
20
|
-
|
19
|
+
ExceptionNotifier.ignore_if do |exception, opts|
|
20
|
+
opts.key?(:env) && from_crawler(opts[:env], ignore_crawlers)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
@ignore_cascade_pass = options.delete(:ignore_cascade_pass) { true }
|
25
25
|
|
26
|
-
options.each do |notifier_name,
|
27
|
-
ExceptionNotifier.register_exception_notifier(notifier_name,
|
26
|
+
options.each do |notifier_name, opts|
|
27
|
+
ExceptionNotifier.register_exception_notifier(notifier_name, opts)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
data/lib/exception_notifier.rb
CHANGED
@@ -24,7 +24,7 @@ module ExceptionNotifier
|
|
24
24
|
|
25
25
|
# Define a set of exceptions to be ignored, ie, dont send notifications when any of them are raised.
|
26
26
|
mattr_accessor :ignored_exceptions
|
27
|
-
@@ignored_exceptions = %w{ActiveRecord::RecordNotFound AbstractController::ActionNotFound ActionController::RoutingError ActionController::UnknownFormat ActionController::UrlGenerationError}
|
27
|
+
@@ignored_exceptions = %w{ActiveRecord::RecordNotFound Mongoid::Errors::DocumentNotFound AbstractController::ActionNotFound ActionController::RoutingError ActionController::UnknownFormat ActionController::UrlGenerationError}
|
28
28
|
|
29
29
|
mattr_accessor :testing_mode
|
30
30
|
@@testing_mode = false
|
@@ -8,6 +8,7 @@ module ExceptionNotifier
|
|
8
8
|
super
|
9
9
|
begin
|
10
10
|
@ignore_data_if = options[:ignore_data_if]
|
11
|
+
@backtrace_lines = options[:backtrace_lines]
|
11
12
|
|
12
13
|
webhook_url = options.fetch(:webhook_url)
|
13
14
|
@message_opts = options.fetch(:additional_parameters, {})
|
@@ -18,10 +19,21 @@ module ExceptionNotifier
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def call(exception, options={})
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
exception_name = "*#{exception.class.to_s =~ /^[aeiou]/i ? 'An' : 'A'}* `#{exception.class.to_s}`"
|
23
|
+
|
24
|
+
if options[:env].nil?
|
25
|
+
data = options[:data] || {}
|
26
|
+
text = "#{exception_name} *occured in background*\n"
|
27
|
+
else
|
28
|
+
env = options[:env]
|
29
|
+
data = (env['exception_notifier.exception_data'] || {}).merge(options[:data] || {})
|
30
|
+
|
31
|
+
kontroller = env['action_controller.instance']
|
32
|
+
request = "#{env['REQUEST_METHOD']} <#{env['REQUEST_URI']}>"
|
33
|
+
text = "#{exception_name} *occurred while* `#{env['REQUEST_METHOD']} <#{env['REQUEST_URI']}>`"
|
34
|
+
text += " *was processed by* `#{kontroller.controller_name}##{kontroller.action_name}`" if kontroller
|
35
|
+
text += "\n"
|
36
|
+
end
|
25
37
|
|
26
38
|
clean_message = exception.message.gsub("`", "'")
|
27
39
|
fields = [ { title: 'Exception', value: clean_message} ]
|
@@ -29,7 +41,7 @@ module ExceptionNotifier
|
|
29
41
|
fields.push({ title: 'Hostname', value: Socket.gethostname })
|
30
42
|
|
31
43
|
if exception.backtrace
|
32
|
-
formatted_backtrace = "```#{exception.backtrace.join("\n")}```"
|
44
|
+
formatted_backtrace = @backtrace_lines ? "```#{exception.backtrace.first(@backtrace_lines).join("\n")}```" : "```#{exception.backtrace.join("\n")}```"
|
33
45
|
fields.push({ title: 'Backtrace', value: formatted_backtrace })
|
34
46
|
end
|
35
47
|
|
@@ -40,8 +40,8 @@ module ExceptionNotifier
|
|
40
40
|
options[:body][:session] = request.session
|
41
41
|
options[:body][:environment] = request.filtered_env
|
42
42
|
end
|
43
|
-
send_notice(exception, options, nil, @default_options) do |
|
44
|
-
HTTParty.send(http_method, url,
|
43
|
+
send_notice(exception, options, nil, @default_options) do |_, _|
|
44
|
+
HTTParty.send(http_method, url, options)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
@@ -13,7 +13,7 @@ Resque::Failure.backend = Resque::Failure::Multiple
|
|
13
13
|
|
14
14
|
ExceptionNotification.configure do |config|
|
15
15
|
# Ignore additional exception types.
|
16
|
-
# ActiveRecord::RecordNotFound, AbstractController::ActionNotFound and ActionController::RoutingError are already added.
|
16
|
+
# ActiveRecord::RecordNotFound, Mongoid::Errors::DocumentNotFound, AbstractController::ActionNotFound and ActionController::RoutingError are already added.
|
17
17
|
# config.ignored_exceptions += %w{ActionView::TemplateError CustomError}
|
18
18
|
|
19
19
|
# Adds a condition to decide when an exception must be ignored or not.
|
data/test/dummy/config/boot.rb
CHANGED
@@ -8,9 +8,6 @@ Dummy::Application.configure do
|
|
8
8
|
# and recreated between test runs. Don't rely on the data there!
|
9
9
|
config.cache_classes = true
|
10
10
|
|
11
|
-
# Log error messages when you accidentally call methods on nil.
|
12
|
-
config.whiny_nils = true
|
13
|
-
|
14
11
|
# Show full error reports and disable caching
|
15
12
|
config.consider_all_requests_local = true
|
16
13
|
config.action_controller.perform_caching = false
|
@@ -1,5 +1,11 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
|
2
|
+
|
3
|
+
# silence_warnings trick around require can be removed once
|
4
|
+
# https://github.com/collectiveidea/tinder/pull/77
|
5
|
+
# gets merged and released
|
6
|
+
silence_warnings do
|
7
|
+
require 'tinder'
|
8
|
+
end
|
3
9
|
|
4
10
|
class CampfireNotifierTest < ActiveSupport::TestCase
|
5
11
|
|
@@ -80,7 +86,7 @@ class CampfireNotifierTest < ActiveSupport::TestCase
|
|
80
86
|
end
|
81
87
|
|
82
88
|
def fake_exception
|
83
|
-
|
89
|
+
begin
|
84
90
|
5/0
|
85
91
|
rescue Exception => e
|
86
92
|
e
|
@@ -101,7 +101,7 @@ class EmailNotifierTest < ActiveSupport::TestCase
|
|
101
101
|
end
|
102
102
|
|
103
103
|
test "mail should have a descriptive subject" do
|
104
|
-
assert_match
|
104
|
+
assert_match(/^\[Dummy ERROR\]\s+\(ZeroDivisionError\) "divided by 0"$/, @mail.subject)
|
105
105
|
end
|
106
106
|
|
107
107
|
test "mail should say exception was raised in background at show timestamp" do
|
@@ -165,7 +165,7 @@ class EmailNotifierTest < ActiveSupport::TestCase
|
|
165
165
|
:email_format => :text
|
166
166
|
)
|
167
167
|
|
168
|
-
assert_match
|
168
|
+
assert_match(/invalid_encoding\s+: R__sum__/, mail.encoded)
|
169
169
|
end
|
170
170
|
|
171
171
|
test "should send email using ActionMailer" do
|
@@ -1,5 +1,11 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
|
2
|
+
|
3
|
+
# silence_warnings trick around require can be removed once
|
4
|
+
# https://github.com/hipchat/hipchat-rb/pull/174
|
5
|
+
# gets merged and released
|
6
|
+
silence_warnings do
|
7
|
+
require 'hipchat'
|
8
|
+
end
|
3
9
|
|
4
10
|
class HipchatNotifierTest < ActiveSupport::TestCase
|
5
11
|
|
@@ -152,7 +158,7 @@ class HipchatNotifierTest < ActiveSupport::TestCase
|
|
152
158
|
end
|
153
159
|
|
154
160
|
def fake_exception
|
155
|
-
|
161
|
+
begin
|
156
162
|
5/0
|
157
163
|
rescue Exception => e
|
158
164
|
e
|
@@ -160,7 +166,7 @@ class HipchatNotifierTest < ActiveSupport::TestCase
|
|
160
166
|
end
|
161
167
|
|
162
168
|
def fake_exception_with_html_characters
|
163
|
-
|
169
|
+
begin
|
164
170
|
raise StandardError.new('an error with <html> characters')
|
165
171
|
rescue Exception => e
|
166
172
|
e
|
@@ -12,6 +12,13 @@ class MockSidekiqServer
|
|
12
12
|
end
|
13
13
|
|
14
14
|
class SidekiqTest < ActiveSupport::TestCase
|
15
|
+
setup do
|
16
|
+
@_original_sidekiq_logger = Sidekiq::Logging.logger
|
17
|
+
|
18
|
+
# Silence sidekiq warning to stdout
|
19
|
+
Sidekiq::Logging.logger = nil
|
20
|
+
end
|
21
|
+
|
15
22
|
test "should call notify_exception when sidekiq raises an error" do
|
16
23
|
server = MockSidekiqServer.new
|
17
24
|
message = Hash.new
|
@@ -24,4 +31,8 @@ class SidekiqTest < ActiveSupport::TestCase
|
|
24
31
|
|
25
32
|
server.handle_exception(exception, message)
|
26
33
|
end
|
34
|
+
|
35
|
+
teardown do
|
36
|
+
Sidekiq::Logging.logger = @_original_sidekiq_logger
|
37
|
+
end
|
27
38
|
end
|
@@ -60,6 +60,18 @@ class SlackNotifierTest < ActiveSupport::TestCase
|
|
60
60
|
assert_equal slack_notifier.notifier.username, options[:username]
|
61
61
|
end
|
62
62
|
|
63
|
+
test "should send the notification with specific backtrace lines" do
|
64
|
+
options = {
|
65
|
+
webhook_url: "http://slack.webhook.url",
|
66
|
+
backtrace_lines: 1
|
67
|
+
}
|
68
|
+
|
69
|
+
Slack::Notifier.any_instance.expects(:ping).with('', fake_notification(@exception, {}, nil, 1))
|
70
|
+
|
71
|
+
slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
|
72
|
+
slack_notifier.call(@exception)
|
73
|
+
end
|
74
|
+
|
63
75
|
test "should pass the additional parameters to Slack::Notifier.ping" do
|
64
76
|
options = {
|
65
77
|
webhook_url: "http://slack.webhook.url",
|
@@ -106,7 +118,7 @@ class SlackNotifierTest < ActiveSupport::TestCase
|
|
106
118
|
|
107
119
|
expected_data_string = "foo: bar\njohn: doe\nuser_id: 5"
|
108
120
|
|
109
|
-
Slack::Notifier.any_instance.expects(:ping).with('', fake_notification(@exception, expected_data_string))
|
121
|
+
Slack::Notifier.any_instance.expects(:ping).with('', fake_notification(@exception, notification_options, expected_data_string))
|
110
122
|
slack_notifier = ExceptionNotifier::SlackNotifier.new(options)
|
111
123
|
slack_notifier.call(@exception, notification_options)
|
112
124
|
end
|
@@ -165,12 +177,28 @@ class SlackNotifierTest < ActiveSupport::TestCase
|
|
165
177
|
]
|
166
178
|
end
|
167
179
|
|
168
|
-
def fake_notification(exception = @exception, data_string = nil)
|
169
|
-
|
180
|
+
def fake_notification(exception = @exception, notification_options = {}, data_string = nil, expected_backtrace_lines = nil)
|
181
|
+
exception_name = "*#{exception.class.to_s =~ /^[aeiou]/i ? 'An' : 'A'}* `#{exception.class.to_s}`"
|
182
|
+
if notification_options[:env].nil?
|
183
|
+
text = "#{exception_name} *occured in background*"
|
184
|
+
else
|
185
|
+
env = notification_options[:env]
|
186
|
+
|
187
|
+
kontroller = env['action_controller.instance']
|
188
|
+
request = "#{env['REQUEST_METHOD']} <#{env['REQUEST_URI']}>"
|
189
|
+
|
190
|
+
text = "#{exception_name} *occurred while* `#{request}`"
|
191
|
+
text += " *was processed by* `#{kontroller.controller_name}##{kontroller.action_name}`" if kontroller
|
192
|
+
end
|
193
|
+
|
194
|
+
text += "\n"
|
170
195
|
|
171
196
|
fields = [ { title: 'Exception', value: exception.message} ]
|
172
197
|
fields.push({ title: 'Hostname', value: 'example.com' })
|
173
|
-
|
198
|
+
if exception.backtrace
|
199
|
+
formatted_backtrace = expected_backtrace_lines ? "```#{exception.backtrace.first(expected_backtrace_lines).join("\n")}```" : "```#{exception.backtrace.join("\n")}```"
|
200
|
+
fields.push({ title: 'Backtrace', value: formatted_backtrace })
|
201
|
+
end
|
174
202
|
fields.push({ title: 'Data', value: "```#{data_string}```" }) if data_string
|
175
203
|
|
176
204
|
{ attachments: [ color: 'danger', text: text, fields: fields, mrkdwn_in: %w(text fields) ] }
|
@@ -14,7 +14,7 @@ class WebhookNotifierTest < ActiveSupport::TestCase
|
|
14
14
|
assert_equal response[:body][:exception][:error_class], "ZeroDivisionError"
|
15
15
|
assert_includes response[:body][:exception][:message], "divided by 0"
|
16
16
|
assert_includes response[:body][:exception][:backtrace], "/exception_notification/test/webhook_notifier_test.rb:48"
|
17
|
-
|
17
|
+
|
18
18
|
assert response[:body][:request][:cookies].has_key?(:cookie_item1)
|
19
19
|
assert_equal response[:body][:request][:url], "http://example.com/example"
|
20
20
|
assert_equal response[:body][:request][:ip_address], "192.168.1.1"
|
@@ -25,6 +25,16 @@ class WebhookNotifierTest < ActiveSupport::TestCase
|
|
25
25
|
assert response[:body][:data][:extra_data].has_key?(:data_item1)
|
26
26
|
end
|
27
27
|
|
28
|
+
test "should send webhook notification with correct params data" do
|
29
|
+
url = 'http://localhost:8000'
|
30
|
+
fake_exception.stubs(:backtrace).returns('the backtrace')
|
31
|
+
webhook = ExceptionNotifier::WebhookNotifier.new({:url => url})
|
32
|
+
|
33
|
+
HTTParty.expects(:send).with(:post, url, fake_params)
|
34
|
+
|
35
|
+
webhook.call(fake_exception)
|
36
|
+
end
|
37
|
+
|
28
38
|
test "should call pre/post_callback if specified" do
|
29
39
|
HTTParty.stubs(:send).returns(fake_response)
|
30
40
|
webhook = ExceptionNotifier::WebhookNotifier.new({:url => 'http://localhost:8000'})
|
@@ -58,8 +68,24 @@ class WebhookNotifierTest < ActiveSupport::TestCase
|
|
58
68
|
}
|
59
69
|
end
|
60
70
|
|
71
|
+
def fake_params
|
72
|
+
{
|
73
|
+
:body => {
|
74
|
+
:server => Socket.gethostname,
|
75
|
+
:process => $$,
|
76
|
+
:rails_root => Rails.root,
|
77
|
+
:exception => {
|
78
|
+
:error_class => 'ZeroDivisionError',
|
79
|
+
:message => 'divided by 0'.inspect,
|
80
|
+
:backtrace => 'the backtrace'
|
81
|
+
},
|
82
|
+
:data => {}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
61
87
|
def fake_exception
|
62
|
-
|
88
|
+
@fake_exception ||= begin
|
63
89
|
5/0
|
64
90
|
rescue Exception => e
|
65
91
|
e
|
@@ -3,8 +3,8 @@ require 'test_helper'
|
|
3
3
|
class ExceptionNotifierTest < ActiveSupport::TestCase
|
4
4
|
test "should have default ignored exceptions" do
|
5
5
|
assert_equal ExceptionNotifier.ignored_exceptions,
|
6
|
-
['ActiveRecord::RecordNotFound', '
|
7
|
-
'ActionController::UnknownFormat', 'ActionController::UrlGenerationError']
|
6
|
+
['ActiveRecord::RecordNotFound', 'Mongoid::Errors::DocumentNotFound', 'AbstractController::ActionNotFound',
|
7
|
+
'ActionController::RoutingError', 'ActionController::UnknownFormat', 'ActionController::UrlGenerationError']
|
8
8
|
end
|
9
9
|
|
10
10
|
test "should have email notifier registered" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_notification
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.2.
|
4
|
+
version: 4.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamis Buck
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-07-
|
12
|
+
date: 2016-07-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionmailer
|