pboling-super_exception_notifier 1.6.5 → 1.6.6
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.
- data/VERSION.yml +1 -1
- data/exception_notification.gemspec +4 -2
- data/lib/exception_notifiable.rb +9 -13
- data/lib/exception_notifier.rb +71 -10
- data/rails/app/views/exception_notifiable/method_disabled.html.erb +6 -0
- data/rails/init.rb +6 -3
- data/test/exception_notify_functional_test.rb +34 -17
- metadata +3 -2
data/VERSION.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'super_exception_notifier'
|
3
|
-
s.version = '1.6.
|
4
|
-
s.date = '2009-08-
|
3
|
+
s.version = '1.6.6'
|
4
|
+
s.date = '2009-08-13'
|
5
5
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
6
|
|
7
7
|
s.summary = %q{Allows unhandled (and handled!) exceptions to be captured and sent via email}
|
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.authors = ['Peter Boling', 'Jacques Crocker', 'Jamis Buck']
|
24
24
|
s.email = 'peter.boling@gmail.com'
|
25
25
|
s.homepage = 'http://github.com/pboling/exception_notification'
|
26
|
+
s.require_paths = ["lib"]
|
26
27
|
|
27
28
|
s.has_rdoc = true
|
28
29
|
|
@@ -50,6 +51,7 @@ Gem::Specification.new do |s|
|
|
50
51
|
"rails/app/views/exception_notifiable/423.html",
|
51
52
|
"rails/app/views/exception_notifiable/501.html",
|
52
53
|
"rails/app/views/exception_notifiable/503.html",
|
54
|
+
"rails/app/views/exception_notifiable/method_disabled.html.erb",
|
53
55
|
"views/exception_notifier/_backtrace.html.erb",
|
54
56
|
"views/exception_notifier/_environment.html.erb",
|
55
57
|
"views/exception_notifier/_inspect_model.html.erb",
|
data/lib/exception_notifiable.rb
CHANGED
@@ -16,6 +16,7 @@ module ExceptionNotifiable
|
|
16
16
|
] if defined?(ActionController)
|
17
17
|
end
|
18
18
|
|
19
|
+
# TODO: use ActionController::StatusCodes
|
19
20
|
HTTP_ERROR_CODES = {
|
20
21
|
"400" => "Bad Request",
|
21
22
|
"403" => "Forbidden",
|
@@ -141,28 +142,27 @@ module ExceptionNotifiable
|
|
141
142
|
# OTW the error class is listed!
|
142
143
|
status_code = status_code_for_exception(exception)
|
143
144
|
if status_code == '200'
|
144
|
-
notify_and_render_error_template(status_code, request, exception,
|
145
|
+
notify_and_render_error_template(status_code, request, exception, ExceptionNotifier.get_view_path_for_class(exception, self.class.exception_notifier_verbose))
|
145
146
|
else
|
146
|
-
notify_and_render_error_template(status_code, request, exception)
|
147
|
+
notify_and_render_error_template(status_code, request, exception, ExceptionNotifier.get_view_path_for_status_code(status_code, self.class.exception_notifier_verbose))
|
147
148
|
end
|
148
149
|
end
|
149
150
|
|
150
|
-
def notify_and_render_error_template(status_cd, request, exception, file_path
|
151
|
+
def notify_and_render_error_template(status_cd, request, exception, file_path)
|
151
152
|
status = self.class.http_error_codes[status_cd] ? status_cd + " " + self.class.http_error_codes[status_cd] : status_cd
|
152
|
-
file = file_path ? ExceptionNotifier.get_view_path(file_path) : ExceptionNotifier.get_view_path(status_cd)
|
153
153
|
data = get_exception_data
|
154
154
|
send_email = should_notify_on_exception?(exception, status_cd)
|
155
155
|
send_web_hooks = !ExceptionNotifier.config[:web_hooks].empty?
|
156
156
|
the_blamed = ExceptionNotifier.config[:git_repo_path].nil? ? nil : lay_blame(exception)
|
157
157
|
|
158
158
|
# Debugging output
|
159
|
-
verbose_output(exception, status_cd,
|
159
|
+
verbose_output(exception, status_cd, file_path, send_email, send_web_hooks, request, the_blamed) if self.class.exception_notifier_verbose
|
160
160
|
# Send the email before rendering to avert possible errors on render preventing the email from being sent.
|
161
161
|
perform_exception_notify_mailing(exception, data, request, the_blamed) if send_email
|
162
162
|
# Send Web Hook requests
|
163
163
|
HooksNotifier.deliver_exception_to_web_hooks(ExceptionNotifier.config, exception, self, request, data, the_blamed) if send_web_hooks
|
164
164
|
# Render the error page to the end user
|
165
|
-
render_error_template(
|
165
|
+
render_error_template(file_path, status)
|
166
166
|
end
|
167
167
|
|
168
168
|
def get_exception_data
|
@@ -184,16 +184,16 @@ module ExceptionNotifiable
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
-
def verbose_output(exception, status_cd,
|
187
|
+
def verbose_output(exception, status_cd, file_path, send_email, send_web_hooks, request = nil, the_blamed = nil)
|
188
188
|
puts "[EXCEPTION] #{exception}"
|
189
189
|
puts "[EXCEPTION CLASS] #{exception.class}"
|
190
190
|
puts "[EXCEPTION STATUS_CD] #{status_cd}"
|
191
191
|
puts "[ERROR LAYOUT] #{self.class.error_layout}" if self.class.error_layout
|
192
192
|
puts "[ERROR VIEW PATH] #{ExceptionNotifier.config[:view_path]}" if !ExceptionNotifier.nil? && !ExceptionNotifier.config[:view_path].nil?
|
193
|
-
puts "[ERROR
|
193
|
+
puts "[ERROR FILE PATH] #{file_path.inspect}"
|
194
194
|
puts "[ERROR EMAIL] #{send_email ? "YES" : "NO"}"
|
195
195
|
puts "[ERROR WEB HOOKS] #{send_web_hooks ? "YES" : "NO"}"
|
196
|
-
puts "[COMPAT MODE] #{ExceptionNotifierHelper::COMPAT_MODE ? "
|
196
|
+
puts "[COMPAT MODE] #{ExceptionNotifierHelper::COMPAT_MODE ? "YES" : "NO"}"
|
197
197
|
puts "[THE BLAMED] #{the_blamed}"
|
198
198
|
req = request ? " for request_uri=#{request.request_uri} and env=#{request.env.inspect}" : ""
|
199
199
|
logger.error("render_error(#{status_cd}, #{self.class.http_error_codes[status_cd]}) invoked#{req}") if !logger.nil?
|
@@ -227,10 +227,6 @@ module ExceptionNotifiable
|
|
227
227
|
self.class.rails_error_classes[exception.class].nil? ? '500' : self.class.rails_error_classes[exception.class].blank? ? '200' : self.class.rails_error_classes[exception.class]
|
228
228
|
end
|
229
229
|
|
230
|
-
def exception_to_filename(exception)
|
231
|
-
exception.to_s.delete(':').gsub( /([A-Za-z])([A-Z])/, '\1' << '_' << '\2' ).downcase
|
232
|
-
end
|
233
|
-
|
234
230
|
def lay_blame(exception)
|
235
231
|
error = {}
|
236
232
|
unless(ExceptionNotifier.config[:git_repo_path].nil?)
|
data/lib/exception_notifier.rb
CHANGED
@@ -37,16 +37,77 @@ class ExceptionNotifier < ActionMailer::Base
|
|
37
37
|
|
38
38
|
def self.reloadable?() false end
|
39
39
|
|
40
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
# Returns an array of potential filenames to look for
|
41
|
+
# eg. For the Exception Class - SuperExceptionNotifier::CustomExceptionClasses::MethodDisabled
|
42
|
+
# the filename handles are:
|
43
|
+
# super_exception_notifier_custom_exception_classes_method_disabled
|
44
|
+
# method_disabled
|
45
|
+
def self.exception_to_filenames(exception)
|
46
|
+
filenames = []
|
47
|
+
e = exception.to_s
|
48
|
+
filenames << ExceptionNotifier.filenamify(e)
|
49
|
+
|
50
|
+
last_colon = e.rindex(':')
|
51
|
+
unless last_colon.nil?
|
52
|
+
filenames << ExceptionNotifier.filenamify(e[(last_colon + 1)..(e.length - 1)])
|
53
|
+
end
|
54
|
+
filenames
|
55
|
+
end
|
56
|
+
|
57
|
+
# Converts Stringified Class Names to acceptable filename handles with underscores
|
58
|
+
def self.filenamify(str)
|
59
|
+
str.delete(':').gsub( /([A-Za-z])([A-Z])/, '\1' << '_' << '\2').downcase
|
60
|
+
end
|
61
|
+
|
62
|
+
# What is the path of the file we will render to the user based on a given status code?
|
63
|
+
def self.get_view_path_for_status_code(status_cd, verbose = false)
|
64
|
+
file_name = ExceptionNotifier.get_view_path(status_cd, verbose)
|
65
|
+
#ExceptionNotifierHelper::COMPAT_MODE ? "#{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/500.html" : "500.html"
|
66
|
+
file_name.nil? ? self.catch_all(verbose) : file_name
|
67
|
+
end
|
68
|
+
|
69
|
+
# def self.get_view_path_for_files(filenames = [])
|
70
|
+
# filepaths = filenames.map do |file|
|
71
|
+
# ExceptionNotifier.get_view_path(file)
|
72
|
+
# end.compact
|
73
|
+
# filepaths.empty? ? "#{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/500.html" : filepaths.first
|
74
|
+
# end
|
75
|
+
|
76
|
+
# What is the path of the file we will render to the user based on a given exception class?
|
77
|
+
def self.get_view_path_for_class(exception, verbose = false)
|
78
|
+
return self.catch_all if exception.nil?
|
79
|
+
return self.catch_all unless exception.is_a?(StandardError) || exception.is_a?(Class) # For some reason exception.is_a?(Class) works in console, but not when running in mongrel (ALWAYS returns false)?!?!?
|
80
|
+
filepaths = ExceptionNotifier.exception_to_filenames(exception).map do |file|
|
81
|
+
ExceptionNotifier.get_view_path(file, verbose)
|
82
|
+
end.compact
|
83
|
+
filepaths.empty? ? self.catch_all(verbose) : filepaths.first
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.catch_all(verbose = false)
|
87
|
+
puts "[CATCH ALL INVOKED] #{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/500.html" if verbose
|
88
|
+
"#{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/500.html"
|
89
|
+
end
|
90
|
+
|
91
|
+
# Check the usual suspects
|
92
|
+
def self.get_view_path(file_name, verbose = false)
|
93
|
+
if File.exist?("#{RAILS_ROOT}/public/#{file_name}.html")
|
94
|
+
puts "[FOUND FILE] #{RAILS_ROOT}/public/#{file_name}.html" if verbose
|
95
|
+
"#{RAILS_ROOT}/public/#{file_name}.html"
|
96
|
+
elsif !config[:view_path].nil? && File.exist?("#{RAILS_ROOT}/#{config[:view_path]}/#{file_name}.html.erb")
|
97
|
+
puts "[FOUND FILE] #{RAILS_ROOT}/#{config[:view_path]}/#{file_name}.html.erb" if verbose
|
98
|
+
"#{RAILS_ROOT}/#{config[:view_path]}/#{file_name}.html.erb"
|
99
|
+
elsif !config[:view_path].nil? && File.exist?("#{RAILS_ROOT}/#{config[:view_path]}/#{file_name}.html")
|
100
|
+
puts "[FOUND FILE] #{RAILS_ROOT}/#{config[:view_path]}/#{file_name}.html" if verbose
|
101
|
+
"#{RAILS_ROOT}/#{config[:view_path]}/#{file_name}.html"
|
102
|
+
elsif File.exist?("#{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/#{file_name}.html.erb")
|
103
|
+
puts "[FOUND FILE] #{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/#{file_name}.html.erb" if verbose
|
104
|
+
"#{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/#{file_name}.html.erb"
|
105
|
+
elsif File.exist?("#{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/#{file_name}.html")
|
106
|
+
#ExceptionNotifierHelper::COMPAT_MODE ? "#{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/#{file_name}.html" : "#{status_cd}.html"
|
107
|
+
puts "[FOUND FILE] #{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/#{file_name}.html" if verbose
|
108
|
+
"#{File.dirname(__FILE__)}/../rails/app/views/exception_notifiable/#{file_name}.html"
|
109
|
+
else
|
110
|
+
nil
|
50
111
|
end
|
51
112
|
end
|
52
113
|
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<!-- This file lives in gems/super_exception_notifier/rails/app/views/exception_notifiable/method_disabled.html.erb. See Readme for instructions on customizing. -->
|
2
|
+
<div class="dialog">
|
3
|
+
<h1>Method Disabled.</h1>
|
4
|
+
|
5
|
+
<p>You attempted to access <%= params[:controller].humanize %> <%= params[:action] %> but that method is currently disabled. Reloading the page will not help unless and until the method is enabled by the system administrator.</p>
|
6
|
+
</div>
|
data/rails/init.rb
CHANGED
@@ -13,6 +13,9 @@ require "notifiable"
|
|
13
13
|
|
14
14
|
Object.class_eval do include Notifiable end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
#It appears that the view path is auto-added by rails... hmmm.
|
17
|
+
#if ActionController::Base.respond_to?(:append_view_path)
|
18
|
+
# puts "view path before: #{ActionController::Base.view_paths}"
|
19
|
+
# ActionController::Base.append_view_path(File.join(File.dirname(__FILE__), 'app', 'views','exception_notifiable'))
|
20
|
+
# puts "view path After: #{ActionController::Base.view_paths}"
|
21
|
+
#end
|
@@ -22,21 +22,34 @@ class ExceptionNotifyFunctionalTest < ActionController::TestCase
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def test_view_path_200;
|
26
|
-
def test_view_path_400;
|
27
|
-
def test_view_path_403;
|
28
|
-
def test_view_path_404;
|
29
|
-
def test_view_path_405;
|
30
|
-
def test_view_path_410;
|
31
|
-
def test_view_path_418;
|
32
|
-
def test_view_path_422;
|
33
|
-
def test_view_path_423;
|
34
|
-
def test_view_path_500;
|
35
|
-
def test_view_path_501;
|
36
|
-
def test_view_path_503;
|
37
|
-
def test_view_path_nil;
|
38
|
-
def test_view_path_empty;
|
39
|
-
def test_view_path_nonsense;
|
25
|
+
def test_view_path_200; assert_view_path_for_status_cd_is_string("200"); end
|
26
|
+
def test_view_path_400; assert_view_path_for_status_cd_is_string("400"); end
|
27
|
+
def test_view_path_403; assert_view_path_for_status_cd_is_string("403"); end
|
28
|
+
def test_view_path_404; assert_view_path_for_status_cd_is_string("404"); end
|
29
|
+
def test_view_path_405; assert_view_path_for_status_cd_is_string("405"); end
|
30
|
+
def test_view_path_410; assert_view_path_for_status_cd_is_string("410"); end
|
31
|
+
def test_view_path_418; assert_view_path_for_status_cd_is_string("422"); end
|
32
|
+
def test_view_path_422; assert_view_path_for_status_cd_is_string("422"); end
|
33
|
+
def test_view_path_423; assert_view_path_for_status_cd_is_string("423"); end
|
34
|
+
def test_view_path_500; assert_view_path_for_status_cd_is_string("500"); end
|
35
|
+
def test_view_path_501; assert_view_path_for_status_cd_is_string("501"); end
|
36
|
+
def test_view_path_503; assert_view_path_for_status_cd_is_string("503"); end
|
37
|
+
def test_view_path_nil; assert_view_path_for_status_cd_is_string(nil); end
|
38
|
+
def test_view_path_empty; assert_view_path_for_status_cd_is_string(""); end
|
39
|
+
def test_view_path_nonsense; assert_view_path_for_status_cd_is_string("slartibartfarst"); end
|
40
|
+
def test_view_path_class;
|
41
|
+
exception = SuperExceptionNotifier::CustomExceptionClasses::MethodDisabled
|
42
|
+
assert_view_path_for_class_is_string(exception);
|
43
|
+
assert ExceptionNotifier.get_view_path_for_class(exception).match("/rails/app/views/exception_notifiable/method_disabled.html.erb")
|
44
|
+
end
|
45
|
+
def test_view_path_class_nil; assert_view_path_for_class_is_string(nil); end
|
46
|
+
def test_view_path_class_empty; assert_view_path_for_class_is_string(""); end
|
47
|
+
def test_view_path_class_nonsense; assert_view_path_for_class_is_string("slartibartfarst"); end
|
48
|
+
def test_view_path_class_integer; assert_view_path_for_class_is_string(Integer); end
|
49
|
+
|
50
|
+
def test_exception_to_filenames
|
51
|
+
assert(["super_exception_notifier_custom_exception_classes_method_disabled", "method_disabled"] == ExceptionNotifier.exception_to_filenames(SuperExceptionNotifier::CustomExceptionClasses::MethodDisabled))
|
52
|
+
end
|
40
53
|
|
41
54
|
def test_old_style_where_requests_are_local
|
42
55
|
ActionController::Base.consider_all_requests_local = true
|
@@ -81,8 +94,12 @@ class ExceptionNotifyFunctionalTest < ActionController::TestCase
|
|
81
94
|
|
82
95
|
private
|
83
96
|
|
84
|
-
def
|
85
|
-
assert(ExceptionNotifier.
|
97
|
+
def assert_view_path_for_status_cd_is_string(status)
|
98
|
+
assert(ExceptionNotifier.get_view_path_for_status_code(status).is_a?(String), "View Path is not a string for status code '#{status}'")
|
99
|
+
end
|
100
|
+
|
101
|
+
def assert_view_path_for_class_is_string(exception)
|
102
|
+
assert(ExceptionNotifier.get_view_path_for_class(exception).is_a?(String), "View Path is not a string for exception '#{exception}'")
|
86
103
|
end
|
87
104
|
|
88
105
|
def assert_error_mail_contains(text)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pboling-super_exception_notifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Boling
|
@@ -11,7 +11,7 @@ autorequire:
|
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
13
|
|
14
|
-
date: 2009-08-
|
14
|
+
date: 2009-08-13 00:00:00 -07:00
|
15
15
|
default_executable:
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
@@ -55,6 +55,7 @@ files:
|
|
55
55
|
- rails/app/views/exception_notifiable/423.html
|
56
56
|
- rails/app/views/exception_notifiable/501.html
|
57
57
|
- rails/app/views/exception_notifiable/503.html
|
58
|
+
- rails/app/views/exception_notifiable/method_disabled.html.erb
|
58
59
|
- views/exception_notifier/_backtrace.html.erb
|
59
60
|
- views/exception_notifier/_environment.html.erb
|
60
61
|
- views/exception_notifier/_inspect_model.html.erb
|