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,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "active_support/core_ext/time"
|
4
|
+
require "action_dispatch"
|
5
5
|
|
6
6
|
module ExceptionNotifier
|
7
7
|
class Formatter
|
@@ -27,7 +27,7 @@ module ExceptionNotifier
|
|
27
27
|
if env
|
28
28
|
"⚠️ Error occurred in #{env} ⚠️"
|
29
29
|
else
|
30
|
-
|
30
|
+
"⚠️ Error occurred ⚠️"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -38,10 +38,10 @@ module ExceptionNotifier
|
|
38
38
|
#
|
39
39
|
def subtitle
|
40
40
|
errors_text = if errors_count > 1
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
errors_count
|
42
|
+
else
|
43
|
+
/^[aeiou]/i.match?(exception.class.to_s) ? "An" : "A"
|
44
|
+
end
|
45
45
|
|
46
46
|
in_action = " in *#{controller_and_action}*" if controller
|
47
47
|
|
@@ -64,13 +64,13 @@ module ExceptionNotifier
|
|
64
64
|
return unless request
|
65
65
|
|
66
66
|
[
|
67
|
-
|
67
|
+
"```",
|
68
68
|
"* url : #{request.original_url}",
|
69
69
|
"* http_method : #{request.method}",
|
70
70
|
"* ip_address : #{request.remote_ip}",
|
71
71
|
"* parameters : #{request.filtered_parameters}",
|
72
72
|
"* timestamp : #{Time.current}",
|
73
|
-
|
73
|
+
"```"
|
74
74
|
].join("\n")
|
75
75
|
end
|
76
76
|
|
@@ -90,9 +90,9 @@ module ExceptionNotifier
|
|
90
90
|
|
91
91
|
text = []
|
92
92
|
|
93
|
-
text <<
|
93
|
+
text << "```"
|
94
94
|
backtrace.first(3).each { |line| text << "* #{line}" }
|
95
|
-
text <<
|
95
|
+
text << "```"
|
96
96
|
|
97
97
|
text.join("\n")
|
98
98
|
end
|
@@ -119,7 +119,7 @@ module ExceptionNotifier
|
|
119
119
|
end
|
120
120
|
|
121
121
|
def controller
|
122
|
-
env[
|
122
|
+
env["action_controller.instance"] if env
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "active_support/deprecation"
|
4
4
|
|
5
5
|
module ExceptionNotifier
|
6
6
|
class Notifier
|
7
7
|
def self.exception_notification(env, exception, options = {})
|
8
8
|
ActiveSupport::Deprecation.warn(
|
9
|
-
|
9
|
+
"Please use ExceptionNotifier.notify_exception(exception, options.merge(env: env))."
|
10
10
|
)
|
11
11
|
ExceptionNotifier.registered_exception_notifier(:email).create_email(exception, options.merge(env: env))
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.background_exception_notification(exception, options = {})
|
15
|
-
ActiveSupport::Deprecation.warn
|
15
|
+
ActiveSupport::Deprecation.warn "Please use ExceptionNotifier.notify_exception(exception, options)."
|
16
16
|
ExceptionNotifier.registered_exception_notifier(:email).create_email(exception, options)
|
17
17
|
end
|
18
18
|
end
|
@@ -15,15 +15,15 @@ module ExceptionNotifier
|
|
15
15
|
|
16
16
|
webhook_url = options.fetch(:webhook_url)
|
17
17
|
@message_opts = options.fetch(:additional_parameters, {})
|
18
|
-
@color = @message_opts.delete(:color) {
|
18
|
+
@color = @message_opts.delete(:color) { "danger" }
|
19
19
|
@notifier = Slack::Notifier.new webhook_url, options
|
20
|
-
rescue
|
20
|
+
rescue
|
21
21
|
@notifier = nil
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def call(exception, options = {})
|
26
|
-
clean_message = exception.message.tr(
|
26
|
+
clean_message = exception.message.tr("`", "'")
|
27
27
|
attchs = attchs(exception, clean_message, options)
|
28
28
|
|
29
29
|
return unless valid?
|
@@ -32,7 +32,7 @@ module ExceptionNotifier
|
|
32
32
|
send_notice(*args) do |_msg, message_opts|
|
33
33
|
message_opts[:channel] = options[:channel] if options.key?(:channel)
|
34
34
|
|
35
|
-
@notifier.ping
|
35
|
+
@notifier.ping "", message_opts
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -64,25 +64,25 @@ module ExceptionNotifier
|
|
64
64
|
errors_count = options[:accumulated_errors_count].to_i
|
65
65
|
|
66
66
|
measure_word = if errors_count > 1
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
errors_count
|
68
|
+
else
|
69
|
+
/^[aeiou]/i.match?(exception_class.to_s) ? "An" : "A"
|
70
|
+
end
|
71
71
|
|
72
72
|
exception_name = "*#{measure_word}* `#{exception_class}`"
|
73
73
|
env = options[:env]
|
74
74
|
|
75
75
|
options[:headers] ||= {}
|
76
|
-
options[:headers][
|
76
|
+
options[:headers]["Content-Type"] = "application/json"
|
77
77
|
|
78
78
|
if env.nil?
|
79
79
|
data = options[:data] || {}
|
80
80
|
text = "#{exception_name} *occured in background*\n"
|
81
81
|
else
|
82
|
-
data = (env[
|
82
|
+
data = (env["exception_notifier.exception_data"] || {}).merge(options[:data] || {})
|
83
83
|
|
84
|
-
kontroller = env[
|
85
|
-
request = "#{env[
|
84
|
+
kontroller = env["action_controller.instance"]
|
85
|
+
request = "#{env["REQUEST_METHOD"]} <#{env["REQUEST_URI"]}>"
|
86
86
|
text = "#{exception_name} *occurred while* `#{request}`"
|
87
87
|
text += " *was processed by* `#{kontroller.controller_name}##{kontroller.action_name}`" if kontroller
|
88
88
|
text += "\n"
|
@@ -93,19 +93,19 @@ module ExceptionNotifier
|
|
93
93
|
|
94
94
|
def fields(clean_message, backtrace, data)
|
95
95
|
fields = [
|
96
|
-
{
|
97
|
-
{
|
96
|
+
{title: "Exception", value: clean_message},
|
97
|
+
{title: "Hostname", value: Socket.gethostname}
|
98
98
|
]
|
99
99
|
|
100
100
|
if backtrace
|
101
101
|
formatted_backtrace = "```#{backtrace.first(@backtrace_lines).join("\n")}```"
|
102
|
-
fields << {
|
102
|
+
fields << {title: "Backtrace", value: formatted_backtrace}
|
103
103
|
end
|
104
104
|
|
105
105
|
unless data.empty?
|
106
106
|
deep_reject(data, @ignore_data_if) if @ignore_data_if.is_a?(Proc)
|
107
107
|
data_string = data.map { |k, v| "#{k}: #{v}" }.join("\n")
|
108
|
-
fields << {
|
108
|
+
fields << {title: "Data", value: "```#{data_string}```"}
|
109
109
|
end
|
110
110
|
|
111
111
|
fields.concat(@additional_fields) if @additional_fields
|
@@ -37,7 +37,7 @@ module ExceptionNotifier
|
|
37
37
|
def build_subject(exception, options)
|
38
38
|
subject =
|
39
39
|
"#{options[:sns_prefix]} - #{accumulated_exception_name(exception, options)} occurred"
|
40
|
-
subject.length > 120 ? subject[0...120] +
|
40
|
+
(subject.length > 120) ? subject[0...120] + "..." : subject
|
41
41
|
end
|
42
42
|
|
43
43
|
def build_message(exception, options)
|
@@ -49,9 +49,9 @@ module ExceptionNotifier
|
|
49
49
|
else
|
50
50
|
env = options[:env]
|
51
51
|
|
52
|
-
kontroller = env[
|
53
|
-
data = (env[
|
54
|
-
request = "#{env[
|
52
|
+
kontroller = env["action_controller.instance"]
|
53
|
+
data = (env["exception_notifier.exception_data"] || {}).merge(options[:data] || {})
|
54
|
+
request = "#{env["REQUEST_METHOD"]} <#{env["REQUEST_URI"]}>"
|
55
55
|
|
56
56
|
text = "#{exception_name} occurred while #{request}"
|
57
57
|
text += " was processed by #{kontroller.controller_name}##{kontroller.action_name}\n" if kontroller
|
@@ -71,17 +71,17 @@ module ExceptionNotifier
|
|
71
71
|
errors_count = options[:accumulated_errors_count].to_i
|
72
72
|
|
73
73
|
measure_word = if errors_count > 1
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
74
|
+
errors_count
|
75
|
+
else
|
76
|
+
/^[aeiou]/i.match?(exception.class.to_s) ? "An" : "A"
|
77
|
+
end
|
78
78
|
|
79
79
|
"#{measure_word} #{exception.class}"
|
80
80
|
end
|
81
81
|
|
82
82
|
def default_options
|
83
83
|
{
|
84
|
-
sns_prefix:
|
84
|
+
sns_prefix: "[ERROR]",
|
85
85
|
backtrace_lines: 10
|
86
86
|
}
|
87
87
|
end
|
@@ -1,15 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "action_dispatch"
|
4
|
+
require "active_support/core_ext/time"
|
5
|
+
require "json"
|
6
6
|
|
7
7
|
module ExceptionNotifier
|
8
8
|
class TeamsNotifier < BaseNotifier
|
9
9
|
include ExceptionNotifier::BacktraceCleaner
|
10
10
|
|
11
11
|
class MissingController
|
12
|
-
def method_missing(*args, &block)
|
12
|
+
def method_missing(*args, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def respond_to_missing?(*args)
|
16
|
+
end
|
13
17
|
end
|
14
18
|
|
15
19
|
attr_accessor :httparty
|
@@ -37,15 +41,15 @@ module ExceptionNotifier
|
|
37
41
|
if @env.nil?
|
38
42
|
@controller = @request_items = nil
|
39
43
|
else
|
40
|
-
@controller = @env[
|
41
|
-
@additional_exception_data = @env[
|
44
|
+
@controller = @env["action_controller.instance"] || MissingController.new
|
45
|
+
@additional_exception_data = @env["exception_notifier.exception_data"]
|
42
46
|
request = ActionDispatch::Request.new(@env)
|
43
47
|
|
44
|
-
@request_items = {
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
@request_items = {url: request.original_url,
|
49
|
+
http_method: request.method,
|
50
|
+
ip_address: request.remote_ip,
|
51
|
+
parameters: request.filtered_parameters,
|
52
|
+
timestamp: Time.current}
|
49
53
|
|
50
54
|
end
|
51
55
|
|
@@ -53,7 +57,7 @@ module ExceptionNotifier
|
|
53
57
|
|
54
58
|
@options[:body] = payload.to_json
|
55
59
|
@options[:headers] ||= {}
|
56
|
-
@options[:headers][
|
60
|
+
@options[:headers]["Content-Type"] = "application/json"
|
57
61
|
@options[:debug_output] = $stdout
|
58
62
|
|
59
63
|
@httparty.post(@webhook_url, @options)
|
@@ -63,96 +67,96 @@ module ExceptionNotifier
|
|
63
67
|
|
64
68
|
def message_text
|
65
69
|
text = {
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
70
|
+
"@type" => "MessageCard",
|
71
|
+
"@context" => "http://schema.org/extensions",
|
72
|
+
"summary" => "#{@application_name} Exception Alert",
|
73
|
+
"title" => "⚠️ Exception Occurred in #{env_name} ⚠️",
|
74
|
+
"sections" => [
|
71
75
|
{
|
72
|
-
|
73
|
-
|
76
|
+
"activityTitle" => activity_title,
|
77
|
+
"activitySubtitle" => @exception.message.to_s
|
74
78
|
}
|
75
79
|
],
|
76
|
-
|
80
|
+
"potentialAction" => []
|
77
81
|
}
|
78
82
|
|
79
|
-
text[
|
80
|
-
text[
|
81
|
-
text[
|
82
|
-
text[
|
83
|
+
text["sections"].push details
|
84
|
+
text["potentialAction"].push gitlab_view_link unless @gitlab_url.nil?
|
85
|
+
text["potentialAction"].push gitlab_issue_link unless @gitlab_url.nil?
|
86
|
+
text["potentialAction"].push jira_issue_link unless @jira_url.nil?
|
83
87
|
|
84
88
|
text
|
85
89
|
end
|
86
90
|
|
87
91
|
def details
|
88
92
|
details = {
|
89
|
-
|
90
|
-
|
93
|
+
"title" => "Details",
|
94
|
+
"facts" => []
|
91
95
|
}
|
92
96
|
|
93
|
-
details[
|
94
|
-
details[
|
95
|
-
details[
|
97
|
+
details["facts"].push message_request unless @request_items.nil?
|
98
|
+
details["facts"].push message_backtrace unless @backtrace.nil?
|
99
|
+
details["facts"].push additional_exception_data unless @additional_exception_data.nil?
|
96
100
|
details
|
97
101
|
end
|
98
102
|
|
99
103
|
def activity_title
|
100
104
|
errors_count = @options[:accumulated_errors_count].to_i
|
101
105
|
|
102
|
-
"#{errors_count > 1 ? errors_count :
|
103
|
-
(@controller ? " in *#{controller_and_method}*." :
|
106
|
+
"#{(errors_count > 1) ? errors_count : "A"} *#{@exception.class}* occurred" +
|
107
|
+
(@controller ? " in *#{controller_and_method}*." : ".")
|
104
108
|
end
|
105
109
|
|
106
110
|
def message_request
|
107
111
|
{
|
108
|
-
|
109
|
-
|
112
|
+
"name" => "Request",
|
113
|
+
"value" => "#{hash_presentation(@request_items)}\n "
|
110
114
|
}
|
111
115
|
end
|
112
116
|
|
113
117
|
def message_backtrace(size = 3)
|
114
118
|
text = []
|
115
|
-
size = @backtrace.size < size ? @backtrace.size : size
|
116
|
-
text <<
|
117
|
-
size.times { |i| text <<
|
118
|
-
text <<
|
119
|
+
size = (@backtrace.size < size) ? @backtrace.size : size
|
120
|
+
text << "```"
|
121
|
+
size.times { |i| text << "* " + @backtrace[i] }
|
122
|
+
text << "```"
|
119
123
|
|
120
124
|
{
|
121
|
-
|
122
|
-
|
125
|
+
"name" => "Backtrace",
|
126
|
+
"value" => text.join(" \n").to_s
|
123
127
|
}
|
124
128
|
end
|
125
129
|
|
126
130
|
def additional_exception_data
|
127
131
|
{
|
128
|
-
|
129
|
-
|
132
|
+
"name" => "Data",
|
133
|
+
"value" => "`#{@additional_exception_data}`\n "
|
130
134
|
}
|
131
135
|
end
|
132
136
|
|
133
137
|
def gitlab_view_link
|
134
138
|
{
|
135
|
-
|
136
|
-
|
137
|
-
|
139
|
+
"@type" => "ViewAction",
|
140
|
+
"name" => "\u{1F98A} View in GitLab",
|
141
|
+
"target" => [
|
138
142
|
"#{@gitlab_url}/#{@application_name}"
|
139
143
|
]
|
140
144
|
}
|
141
145
|
end
|
142
146
|
|
143
147
|
def gitlab_issue_link
|
144
|
-
link = [@gitlab_url, @application_name,
|
148
|
+
link = [@gitlab_url, @application_name, "issues", "new"].join("/")
|
145
149
|
params = {
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
+
"issue[title]" => ["[BUG] Error 500 :",
|
151
|
+
controller_and_method,
|
152
|
+
"(#{@exception.class})",
|
153
|
+
@exception.message].compact.join(" ")
|
150
154
|
}.to_query
|
151
155
|
|
152
156
|
{
|
153
|
-
|
154
|
-
|
155
|
-
|
157
|
+
"@type" => "ViewAction",
|
158
|
+
"name" => "\u{1F98A} Create Issue in GitLab",
|
159
|
+
"target" => [
|
156
160
|
"#{link}/?#{params}"
|
157
161
|
]
|
158
162
|
}
|
@@ -160,9 +164,9 @@ module ExceptionNotifier
|
|
160
164
|
|
161
165
|
def jira_issue_link
|
162
166
|
{
|
163
|
-
|
164
|
-
|
165
|
-
|
167
|
+
"@type" => "ViewAction",
|
168
|
+
"name" => "🐞 Create Issue in Jira",
|
169
|
+
"target" => [
|
166
170
|
"#{@jira_url}/secure/CreateIssue!default.jspa"
|
167
171
|
]
|
168
172
|
}
|
@@ -172,7 +176,7 @@ module ExceptionNotifier
|
|
172
176
|
if @controller
|
173
177
|
"#{@controller.controller_name}##{@controller.action_name}"
|
174
178
|
else
|
175
|
-
|
179
|
+
""
|
176
180
|
end
|
177
181
|
end
|
178
182
|
|
@@ -189,7 +193,7 @@ module ExceptionNotifier
|
|
189
193
|
def rails_app_name
|
190
194
|
return unless defined?(Rails) && Rails.respond_to?(:application)
|
191
195
|
|
192
|
-
if ::Gem::Version.new(Rails.version) >= ::Gem::Version.new(
|
196
|
+
if ::Gem::Version.new(Rails.version) >= ::Gem::Version.new("6.0")
|
193
197
|
Rails.application.class.module_parent_name.underscore
|
194
198
|
else
|
195
199
|
Rails.application.class.parent_name.underscore
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "action_dispatch"
|
4
|
+
require "active_support/core_ext/time"
|
5
5
|
|
6
6
|
module ExceptionNotifier
|
7
7
|
class WebhookNotifier < BaseNotifier
|
@@ -26,7 +26,7 @@ module ExceptionNotifier
|
|
26
26
|
message: exception.message.inspect,
|
27
27
|
backtrace: exception.backtrace
|
28
28
|
}
|
29
|
-
options[:body][:data] = (env && env[
|
29
|
+
options[:body][:data] = (env && env["exception_notifier.exception_data"] || {}).merge(options[:data] || {})
|
30
30
|
|
31
31
|
unless env.nil?
|
32
32
|
request = ActionDispatch::Request.new(env)
|
data/lib/exception_notifier.rb
CHANGED
@@ -1,40 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
3
|
+
require "logger"
|
4
|
+
require "active_support/core_ext/string/inflections"
|
5
|
+
require "active_support/core_ext/module/attribute_accessors"
|
6
|
+
require "exception_notifier/base_notifier"
|
7
|
+
require "exception_notifier/modules/error_grouping"
|
8
8
|
|
9
9
|
module ExceptionNotifier
|
10
10
|
include ErrorGrouping
|
11
11
|
|
12
|
-
autoload :BacktraceCleaner,
|
13
|
-
autoload :Formatter,
|
14
|
-
|
15
|
-
autoload :Notifier,
|
16
|
-
autoload :EmailNotifier,
|
17
|
-
autoload :HipchatNotifier,
|
18
|
-
autoload :WebhookNotifier,
|
19
|
-
autoload :IrcNotifier,
|
20
|
-
autoload :SlackNotifier,
|
21
|
-
autoload :MattermostNotifier,
|
22
|
-
autoload :TeamsNotifier,
|
23
|
-
autoload :SnsNotifier,
|
24
|
-
autoload :GoogleChatNotifier,
|
25
|
-
autoload :DatadogNotifier,
|
12
|
+
autoload :BacktraceCleaner, "exception_notifier/modules/backtrace_cleaner"
|
13
|
+
autoload :Formatter, "exception_notifier/modules/formatter"
|
14
|
+
|
15
|
+
autoload :Notifier, "exception_notifier/notifier"
|
16
|
+
autoload :EmailNotifier, "exception_notifier/email_notifier"
|
17
|
+
autoload :HipchatNotifier, "exception_notifier/hipchat_notifier"
|
18
|
+
autoload :WebhookNotifier, "exception_notifier/webhook_notifier"
|
19
|
+
autoload :IrcNotifier, "exception_notifier/irc_notifier"
|
20
|
+
autoload :SlackNotifier, "exception_notifier/slack_notifier"
|
21
|
+
autoload :MattermostNotifier, "exception_notifier/mattermost_notifier"
|
22
|
+
autoload :TeamsNotifier, "exception_notifier/teams_notifier"
|
23
|
+
autoload :SnsNotifier, "exception_notifier/sns_notifier"
|
24
|
+
autoload :GoogleChatNotifier, "exception_notifier/google_chat_notifier"
|
25
|
+
autoload :DatadogNotifier, "exception_notifier/datadog_notifier"
|
26
26
|
|
27
27
|
class UndefinedNotifierError < StandardError; end
|
28
28
|
|
29
29
|
# Define logger
|
30
30
|
mattr_accessor :logger
|
31
|
-
@@logger = Logger.new(
|
31
|
+
@@logger = Logger.new($stdout)
|
32
32
|
|
33
33
|
# Define a set of exceptions to be ignored, ie, dont send notifications when any of them are raised.
|
34
34
|
mattr_accessor :ignored_exceptions
|
35
35
|
@@ignored_exceptions = %w[
|
36
36
|
ActiveRecord::RecordNotFound Mongoid::Errors::DocumentNotFound AbstractController::ActionNotFound
|
37
37
|
ActionController::RoutingError ActionController::UnknownFormat ActionController::UrlGenerationError
|
38
|
+
ActionDispatch::Http::MimeNegotiation::InvalidType Rack::Utils::InvalidParameterError
|
38
39
|
]
|
39
40
|
|
40
41
|
mattr_accessor :testing_mode
|
@@ -84,7 +85,7 @@ module ExceptionNotifier
|
|
84
85
|
raise ArgumentError, "Invalid notifier '#{name}' defined as #{notifier_or_options.inspect}"
|
85
86
|
end
|
86
87
|
end
|
87
|
-
|
88
|
+
alias_method :add_notifier, :register_exception_notifier
|
88
89
|
|
89
90
|
def unregister_exception_notifier(name)
|
90
91
|
@@notifiers.delete(name)
|
@@ -126,7 +127,7 @@ module ExceptionNotifier
|
|
126
127
|
|
127
128
|
def ignored?(exception, options)
|
128
129
|
@@ignores.any? { |condition| condition.call(exception, options) }
|
129
|
-
rescue Exception => e
|
130
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
130
131
|
raise e if @@testing_mode
|
131
132
|
|
132
133
|
logger.warn(
|
@@ -140,7 +141,7 @@ module ExceptionNotifier
|
|
140
141
|
|
141
142
|
condition = @@by_notifier_ignores[notifier]
|
142
143
|
condition.call(exception, options)
|
143
|
-
rescue Exception => e
|
144
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
144
145
|
raise e if @@testing_mode
|
145
146
|
|
146
147
|
logger.warn(<<~"MESSAGE")
|
@@ -159,7 +160,7 @@ module ExceptionNotifier
|
|
159
160
|
def fire_notification(notifier_name, exception, options, &block)
|
160
161
|
notifier = registered_exception_notifier(notifier_name)
|
161
162
|
notifier.call(exception, options, &block)
|
162
|
-
rescue Exception => e
|
163
|
+
rescue Exception => e # standard:disable Lint/RescueException
|
163
164
|
raise e if @@testing_mode
|
164
165
|
|
165
166
|
logger.warn(
|
@@ -176,11 +177,11 @@ module ExceptionNotifier
|
|
176
177
|
register_exception_notifier(name, notifier)
|
177
178
|
rescue NameError => e
|
178
179
|
raise UndefinedNotifierError,
|
179
|
-
|
180
|
+
"No notifier named '#{name}' was found. Please, revise your configuration options. Cause: #{e.message}"
|
180
181
|
end
|
181
182
|
|
182
183
|
def from_crawler(env, ignored_crawlers)
|
183
|
-
agent = env[
|
184
|
+
agent = env["HTTP_USER_AGENT"]
|
184
185
|
Array(ignored_crawlers).any? do |crawler|
|
185
186
|
agent =~ Regexp.new(crawler)
|
186
187
|
end
|
@@ -3,18 +3,18 @@
|
|
3
3
|
module ExceptionNotification
|
4
4
|
module Generators
|
5
5
|
class InstallGenerator < ::Rails::Generators::Base
|
6
|
-
desc
|
6
|
+
desc "Creates a ExceptionNotification initializer."
|
7
7
|
|
8
|
-
source_root File.expand_path(
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
9
9
|
class_option :resque,
|
10
|
-
|
11
|
-
|
10
|
+
type: :boolean,
|
11
|
+
desc: "Add support for sending notifications when errors occur in Resque jobs."
|
12
12
|
class_option :sidekiq,
|
13
|
-
|
14
|
-
|
13
|
+
type: :boolean,
|
14
|
+
desc: "Add support for sending notifications when errors occur in Sidekiq jobs."
|
15
15
|
|
16
16
|
def copy_initializer
|
17
|
-
template
|
17
|
+
template "exception_notification.rb.erb", "config/initializers/exception_notification.rb"
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|