super_exception_notifier 2.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.
- data/MIT-LICENSE +21 -0
- data/README.rdoc +528 -0
- data/VERSION.yml +4 -0
- data/init.rb +1 -0
- data/lib/exception_notifiable.rb +175 -0
- data/lib/exception_notifier.rb +185 -0
- data/lib/exception_notifier_helper.rb +60 -0
- data/lib/notifiable.rb +91 -0
- data/lib/super_exception_notifier/custom_exception_classes.rb +16 -0
- data/lib/super_exception_notifier/custom_exception_methods.rb +50 -0
- data/lib/super_exception_notifier/deprecated_methods.rb +60 -0
- data/lib/super_exception_notifier/git_blame.rb +52 -0
- data/lib/super_exception_notifier/helpful_hashes.rb +66 -0
- data/lib/super_exception_notifier/hooks_notifier.rb +55 -0
- data/lib/super_exception_notifier/notifiable_helper.rb +79 -0
- data/rails/app/views/exception_notifiable/400.html +5 -0
- data/rails/app/views/exception_notifiable/403.html +6 -0
- data/rails/app/views/exception_notifiable/404.html +6 -0
- data/rails/app/views/exception_notifiable/405.html +6 -0
- data/rails/app/views/exception_notifiable/410.html +7 -0
- data/rails/app/views/exception_notifiable/418.html +6 -0
- data/rails/app/views/exception_notifiable/422.html +5 -0
- data/rails/app/views/exception_notifiable/423.html +6 -0
- data/rails/app/views/exception_notifiable/501.html +8 -0
- data/rails/app/views/exception_notifiable/503.html +6 -0
- data/rails/app/views/exception_notifiable/method_disabled.html.erb +6 -0
- data/rails/init.rb +25 -0
- data/tasks/notified_task.rake +15 -0
- data/test/exception_notifiable_test.rb +34 -0
- data/test/exception_notifier_helper_test.rb +76 -0
- data/test/exception_notifier_test.rb +41 -0
- data/test/exception_notify_functional_test.rb +139 -0
- data/test/mocks/controllers.rb +82 -0
- data/test/notifiable_test.rb +79 -0
- data/test/test_helper.rb +32 -0
- data/views/exception_notifier/_backtrace.html.erb +1 -0
- data/views/exception_notifier/_environment.html.erb +14 -0
- data/views/exception_notifier/_inspect_model.html.erb +16 -0
- data/views/exception_notifier/_request.html.erb +8 -0
- data/views/exception_notifier/_session.html.erb +6 -0
- data/views/exception_notifier/_title.html.erb +3 -0
- data/views/exception_notifier/background_exception_notification.text.plain.erb +10 -0
- data/views/exception_notifier/exception_notification.text.plain.erb +15 -0
- metadata +119 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
#Copyright (c) 2008-2009 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
|
4
|
+
module SuperExceptionNotifier
|
5
|
+
module CustomExceptionClasses
|
6
|
+
|
7
|
+
class AccessDenied < StandardError; end
|
8
|
+
class ResourceGone < StandardError; end
|
9
|
+
class NotImplemented < StandardError; end
|
10
|
+
class PageNotFound < StandardError; end
|
11
|
+
class InvalidMethod < StandardError; end
|
12
|
+
class CorruptData < StandardError; end
|
13
|
+
class MethodDisabled < StandardError; end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#Copyright (c) 2008-2009 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
|
4
|
+
module SuperExceptionNotifier
|
5
|
+
module CustomExceptionMethods
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
#For a while after disabling a route/URL that had been functional we should set it to resource gone to inform people to remove bookmarks.
|
10
|
+
def resource_gone
|
11
|
+
raise ResourceGone
|
12
|
+
end
|
13
|
+
#Then for things that have never existed or have not for a long time we call not_implemented
|
14
|
+
def not_implemented
|
15
|
+
raise NotImplemented
|
16
|
+
end
|
17
|
+
#Resources that must be requested with a specific HTTP Method (GET, PUT, POST, DELETE, AJAX, etc) but are requested otherwise should:
|
18
|
+
def invalid_method
|
19
|
+
raise InvalidMethod
|
20
|
+
end
|
21
|
+
#If your ever at a spot in the code that should never get reached, but corrupt data might get you there anyways then this is for you:
|
22
|
+
def corrupt_data
|
23
|
+
raise CorruptData
|
24
|
+
end
|
25
|
+
def page_not_found
|
26
|
+
raise PageNotFound
|
27
|
+
end
|
28
|
+
def record_not_found
|
29
|
+
raise ActiveRecord::RecordNotFound
|
30
|
+
end
|
31
|
+
def method_disabled
|
32
|
+
raise MethodDisabled
|
33
|
+
end
|
34
|
+
#The current user does not have enough privileges to access the requested resource
|
35
|
+
def access_denied
|
36
|
+
raise AccessDenied
|
37
|
+
end
|
38
|
+
|
39
|
+
def generic_error
|
40
|
+
error_stickie("Sorry, an error has occurred.")
|
41
|
+
corrupt_data
|
42
|
+
end
|
43
|
+
|
44
|
+
def invalid_page
|
45
|
+
error_stickie("Sorry, the page number you requested was not valid.")
|
46
|
+
page_not_found
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#Copyright (c) 2008-2009 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
|
4
|
+
module SuperExceptionNotifier
|
5
|
+
module DeprecatedMethods
|
6
|
+
@@namespacing = "Better namespacing to allow for Notifiable and ExceptionNotifiable to have similar APIs"
|
7
|
+
@@rails2ruby = "An effort to make this a 'Ruby' Gem and not a stricly 'Rails' Gem"
|
8
|
+
|
9
|
+
def http_error_codes
|
10
|
+
deprecation_warning("http_error_codes", "error_class_status_codes")
|
11
|
+
error_class_status_codes
|
12
|
+
end
|
13
|
+
|
14
|
+
def http_error_codes=(arg)
|
15
|
+
deprecation_warning("http_error_codes", "error_class_status_codes")
|
16
|
+
error_class_status_codes=(arg)
|
17
|
+
end
|
18
|
+
|
19
|
+
def rails_error_codes
|
20
|
+
deprecation_warning("rails_error_codes", "error_class_status_codes", @@rails2ruby)
|
21
|
+
error_class_status_codes
|
22
|
+
end
|
23
|
+
|
24
|
+
def rails_error_codes=(arg)
|
25
|
+
deprecation_warning("rails_error_codes=", "error_class_status_codes=", @@rails2ruby)
|
26
|
+
error_class_status_codes=(arg)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Now defined in Object class by init.rb & Notifiable module,
|
30
|
+
# so we need to override them for with the controller settings
|
31
|
+
def exception_notifier_verbose
|
32
|
+
deprecation_warning("exception_notifier_verbose", "exception_notifiable_verbose", @@namespacing)
|
33
|
+
exception_notifiable_verbose
|
34
|
+
end
|
35
|
+
def silent_exceptions
|
36
|
+
deprecation_warning("silent_exceptions", "exception_notifiable_silent_exceptions", @@namespacing)
|
37
|
+
exception_notifiable_silent_exceptions
|
38
|
+
end
|
39
|
+
def notification_level
|
40
|
+
deprecation_warning("notification_level", "exception_notifiable_notification_level", @@namespacing)
|
41
|
+
exception_notifiable_notification_level
|
42
|
+
end
|
43
|
+
def exception_notifier_verbose=(arg)
|
44
|
+
deprecation_warning("exception_notifier_verbose=", "exception_notifiable_verbose=", @@namespacing)
|
45
|
+
exception_notifiable_verbose = arg
|
46
|
+
end
|
47
|
+
def silent_exceptions=(arg)
|
48
|
+
deprecation_warning("silent_exceptions=", "exception_notifiable_silent_exceptions=", @@namespacing)
|
49
|
+
exception_notifiable_silent_exceptions = arg
|
50
|
+
end
|
51
|
+
def notification_level=(arg)
|
52
|
+
deprecation_warning("notification_level=", "exception_notifiable_notification_level=", @@namespacing)
|
53
|
+
exception_notifiable_notification_level = arg
|
54
|
+
end
|
55
|
+
|
56
|
+
def deprecation_warning(old, new, reason = "")
|
57
|
+
puts "[DEPRECATION WARNING] ** Method '#{old}' has been replaced by '#{new}', please update your code.#{' Reason for change: ' + reason + '.' if reason}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#Copyright (c) 2008-2009 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
|
4
|
+
module SuperExceptionNotifier
|
5
|
+
module GitBlame
|
6
|
+
|
7
|
+
def lay_blame(exception)
|
8
|
+
error = {}
|
9
|
+
unless(ExceptionNotifier.config[:git_repo_path].nil?)
|
10
|
+
if(exception.class == ActionView::TemplateError)
|
11
|
+
blame = blame_output(exception.line_number, "app/views/#{exception.file_name}")
|
12
|
+
error[:author] = blame[/^author\s.+$/].gsub(/author\s/,'')
|
13
|
+
error[:line] = exception.line_number
|
14
|
+
error[:file] = exception.file_name
|
15
|
+
else
|
16
|
+
exception.backtrace.each do |line|
|
17
|
+
file = exception_in_project?(line[/^.+?(?=:)/])
|
18
|
+
unless(file.nil?)
|
19
|
+
line_number = line[/:\d+:/].gsub(/[^\d]/,'')
|
20
|
+
# Use relative path or weird stuff happens
|
21
|
+
blame = blame_output(line_number, file.gsub(Regexp.new("#{RAILS_ROOT}/"),''))
|
22
|
+
error[:author] = blame[/^author\s.+$/].sub(/author\s/,'')
|
23
|
+
error[:line] = line_number
|
24
|
+
error[:file] = file
|
25
|
+
break
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
error
|
31
|
+
end
|
32
|
+
|
33
|
+
def blame_output(line_number, path)
|
34
|
+
app_directory = Dir.pwd
|
35
|
+
Dir.chdir ExceptionNotifier.config[:git_repo_path]
|
36
|
+
blame = `git blame -p -L #{line_number},#{line_number} #{path}`
|
37
|
+
Dir.chdir app_directory
|
38
|
+
|
39
|
+
blame
|
40
|
+
end
|
41
|
+
|
42
|
+
def exception_in_project?(path) # should be a path like /path/to/broken/thingy.rb
|
43
|
+
dir = File.split(path).first rescue ''
|
44
|
+
if(File.directory?(dir) and !(path =~ /vendor\/plugins/) and !(path =~ /vendor\/gems/) and path.include?(RAILS_ROOT))
|
45
|
+
path
|
46
|
+
else
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
#Copyright (c) 2008-2009 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
|
4
|
+
module SuperExceptionNotifier
|
5
|
+
module HelpfulHashes
|
6
|
+
unless defined?(SILENT_EXCEPTIONS)
|
7
|
+
noiseless = []
|
8
|
+
noiseless << ActiveRecord::RecordNotFound if defined?(ActiveRecord)
|
9
|
+
if defined?(ActionController)
|
10
|
+
noiseless << ActionController::UnknownController
|
11
|
+
noiseless << ActionController::UnknownAction
|
12
|
+
noiseless << ActionController::RoutingError
|
13
|
+
noiseless << ActionController::MethodNotAllowed
|
14
|
+
end
|
15
|
+
SILENT_EXCEPTIONS = noiseless
|
16
|
+
end
|
17
|
+
|
18
|
+
# TODO: use ActionController::StatusCodes
|
19
|
+
HTTP_STATUS_CODES = {
|
20
|
+
"400" => "Bad Request",
|
21
|
+
"403" => "Forbidden",
|
22
|
+
"404" => "Not Found",
|
23
|
+
"405" => "Method Not Allowed",
|
24
|
+
"410" => "Gone",
|
25
|
+
"418" => "I'm a teapot",
|
26
|
+
"422" => "Unprocessable Entity",
|
27
|
+
"423" => "Locked",
|
28
|
+
"500" => "Internal Server Error",
|
29
|
+
"501" => "Not Implemented",
|
30
|
+
"503" => "Service Unavailable"
|
31
|
+
} unless defined?(HTTP_STATUS_CODES)
|
32
|
+
|
33
|
+
def codes_for_error_classes
|
34
|
+
#TODO: Format whitespace
|
35
|
+
classes = {
|
36
|
+
# These are standard errors in rails / ruby
|
37
|
+
NameError => "503",
|
38
|
+
TypeError => "503",
|
39
|
+
RuntimeError => "500",
|
40
|
+
ArgumentError => "500",
|
41
|
+
# These are custom error names defined in lib/super_exception_notifier/custom_exception_classes
|
42
|
+
AccessDenied => "403",
|
43
|
+
PageNotFound => "404",
|
44
|
+
InvalidMethod => "405",
|
45
|
+
ResourceGone => "410",
|
46
|
+
CorruptData => "422",
|
47
|
+
NoMethodError => "500",
|
48
|
+
NotImplemented => "501",
|
49
|
+
MethodDisabled => "200"
|
50
|
+
}
|
51
|
+
# Highly dependent on the verison of rails, so we're very protective about these'
|
52
|
+
classes.merge!({ ActionView::TemplateError => "500"}) if defined?(ActionView) && ActionView.const_defined?(:TemplateError)
|
53
|
+
classes.merge!({ ActiveRecord::RecordNotFound => "400" }) if defined?(ActiveRecord) && ActiveRecord.const_defined?(:RecordNotFound)
|
54
|
+
classes.merge!({ ActiveResource::ResourceNotFound => "404" }) if defined?(ActiveResource) && ActiveResource.const_defined?(:ResourceNotFound)
|
55
|
+
|
56
|
+
if defined?(ActionController)
|
57
|
+
classes.merge!({ ActionController::UnknownController => "404" }) if ActionController.const_defined?(:UnknownController)
|
58
|
+
classes.merge!({ ActionController::MissingTemplate => "404" }) if ActionController.const_defined?(:MissingTemplate)
|
59
|
+
classes.merge!({ ActionController::MethodNotAllowed => "405" }) if ActionController.const_defined?(:MethodNotAllowed)
|
60
|
+
classes.merge!({ ActionController::UnknownAction => "501" }) if ActionController.const_defined?(:UnknownAction)
|
61
|
+
classes.merge!({ ActionController::RoutingError => "404" }) if ActionController.const_defined?(:RoutingError)
|
62
|
+
classes.merge!({ ActionController::InvalidAuthenticityToken => "405" }) if ActionController.const_defined?(:InvalidAuthenticityToken)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module SuperExceptionNotifier
|
5
|
+
module HooksNotifier
|
6
|
+
# Deliver exception data hash to web hooks, if any
|
7
|
+
#
|
8
|
+
def self.deliver_exception_to_web_hooks(config, exception, controller, request, data={}, the_blamed = nil)
|
9
|
+
params = build_web_hook_params(config, exception, controller, request, data, the_blamed)
|
10
|
+
# TODO: use threads here
|
11
|
+
config[:web_hooks].each do |address|
|
12
|
+
post_hook(params, address)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# Parameters hash based on Merb Exceptions example
|
18
|
+
#
|
19
|
+
def self.build_web_hook_params(config, exception, controller, request, data={}, the_blamed = nil)
|
20
|
+
host = (request.env["HTTP_X_FORWARDED_HOST"] || request.env["HTTP_HOST"])
|
21
|
+
p = {
|
22
|
+
'environment' => (defined?(Rails) ? Rails.env : RAILS_ENV),
|
23
|
+
'exceptions' => [{
|
24
|
+
:class => exception.class.to_s,
|
25
|
+
:backtrace => exception.backtrace,
|
26
|
+
:message => exception.message
|
27
|
+
}],
|
28
|
+
'app_name' => config[:app_name],
|
29
|
+
'version' => config[:version],
|
30
|
+
'blame' => "#{the_blamed}"
|
31
|
+
}
|
32
|
+
if !request.nil?
|
33
|
+
p.merge!({'request_url' => "#{request.protocol}#{host}#{request.request_uri}"})
|
34
|
+
p.merge!({'request_action' => request.parameters['action']})
|
35
|
+
p.merge!({'request_params' => request.parameters.inspect})
|
36
|
+
end
|
37
|
+
p.merge!({'request_controller' => controller.class.name}) if !controller.nil?
|
38
|
+
p.merge!({'status' => exception.status}) if exception.respond_to?(:status)
|
39
|
+
return p
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.post_hook(params, address)
|
43
|
+
uri = URI.parse(address)
|
44
|
+
uri.path = '/' if uri.path=='' # set a path if one isn't provided to keep Net::HTTP happy
|
45
|
+
|
46
|
+
headers = { 'Content-Type' => 'text/x-json' }
|
47
|
+
data = params.to_json
|
48
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
49
|
+
http.request_post(uri.path, data, headers)
|
50
|
+
end
|
51
|
+
data
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
#Copyright (c) 2008-2009 Peter H. Boling of 9thBit LLC
|
2
|
+
#Released under the MIT license
|
3
|
+
|
4
|
+
module SuperExceptionNotifier
|
5
|
+
module NotifiableHelper
|
6
|
+
include CustomExceptionClasses
|
7
|
+
include CustomExceptionMethods
|
8
|
+
include HelpfulHashes
|
9
|
+
include GitBlame
|
10
|
+
include HooksNotifier
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def get_method_name
|
15
|
+
if /`(.*)'/.match(caller.first)
|
16
|
+
return $1
|
17
|
+
end
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_exception_data
|
22
|
+
deliverer = self.class.exception_data
|
23
|
+
return case deliverer
|
24
|
+
when nil then {}
|
25
|
+
when Symbol then send(deliverer)
|
26
|
+
when Proc then deliverer.call(self)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def verbose_output(exception, status_cd, file_path, send_email, send_web_hooks, request = nil, the_blamed = nil)
|
31
|
+
puts "[EXCEPTION] #{exception}"
|
32
|
+
puts "[EXCEPTION CLASS] #{exception.class}"
|
33
|
+
puts "[EXCEPTION STATUS_CD] #{status_cd}"
|
34
|
+
puts "[ERROR LAYOUT] #{self.class.error_layout}" if self.class.respond_to?(:error_layout)
|
35
|
+
puts "[ERROR VIEW PATH] #{ExceptionNotifier.config[:view_path]}" if !ExceptionNotifier.nil? && !ExceptionNotifier.config[:view_path].nil?
|
36
|
+
puts "[ERROR FILE PATH] #{file_path.inspect}"
|
37
|
+
puts "[ERROR EMAIL] #{send_email ? "YES" : "NO"}"
|
38
|
+
puts "[ERROR WEB HOOKS] #{send_web_hooks ? "YES" : "NO"}"
|
39
|
+
puts "[COMPAT MODE] #{ExceptionNotifierHelper::COMPAT_MODE ? "YES" : "NO"}"
|
40
|
+
puts "[THE BLAMED] #{the_blamed}"
|
41
|
+
req = request ? " for request_uri=#{request.request_uri} and env=#{request.env.inspect}" : ""
|
42
|
+
logger.error("render_error(#{status_cd}, #{self.class.http_status_codes[status_cd]}) invoked#{req}") if self.class.respond_to?(:http_status_codes) && !logger.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
def perform_exception_notify_mailing(exception, data, request = nil, the_blamed = nil, verbose = false)
|
46
|
+
if ExceptionNotifier.config[:exception_recipients].blank?
|
47
|
+
puts "[EMAIL NOTIFICATION] ExceptionNotifier.config[:exception_recipients] is blank, notification cancelled!" if verbose
|
48
|
+
else
|
49
|
+
class_name = self.respond_to?(:controller_name) ? self.controller_name : self.to_s
|
50
|
+
method_name = self.respond_to?(:action_name) ? self.action_name : get_method_name
|
51
|
+
ExceptionNotifier.deliver_exception_notification(exception, class_name, method_name,
|
52
|
+
request, data, the_blamed)
|
53
|
+
puts "[EMAIL NOTIFICATION] Sent" if verbose
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def should_email_on_exception?(exception, status_cd = nil, verbose = false)
|
58
|
+
notification_level_sends_email? && !ExceptionNotifier.config[:exception_recipients].empty? && should_notify_on_exception?(exception, status_cd, verbose)
|
59
|
+
end
|
60
|
+
|
61
|
+
def should_web_hook_on_exception?(exception, status_cd = nil, verbose = false)
|
62
|
+
notification_level_sends_web_hooks? && !ExceptionNotifier.config[:web_hooks].empty? && should_notify_on_exception?(exception, status_cd, verbose)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Relies on the base class to define be_silent_for_exception?
|
66
|
+
def should_notify_on_exception?(exception, status_cd = nil, verbose = false)
|
67
|
+
# don't notify (email or web hooks) on exceptions raised locally
|
68
|
+
verbose && ExceptionNotifier.config[:skip_local_notification] && is_local? ?
|
69
|
+
"[NOTIFY LOCALLY] NO" :
|
70
|
+
nil
|
71
|
+
return false if ExceptionNotifier.config[:skip_local_notification] && is_local?
|
72
|
+
# don't notify (email or web hooks) exceptions raised that match ExceptionNotifiable.notifiable_silent_exceptions
|
73
|
+
return false if self.be_silent_for_exception?(exception)
|
74
|
+
return true if ExceptionNotifier.config[:notify_error_classes].include?(exception.class)
|
75
|
+
return true if !status_cd.nil? && ExceptionNotifier.config[:notify_error_codes].include?(status_cd)
|
76
|
+
return ExceptionNotifier.config[:notify_other_errors]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<!-- This file lives in gems/super_exception_notifier/rails/app/views/exception_notifiable/400.html. See Readme for instructions on customizing. -->
|
2
|
+
<div class="dialog">
|
3
|
+
<h1>Unable to Process Requested Data</h1>
|
4
|
+
<p>Reloading the page will probably not help.</p>
|
5
|
+
</div>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<!-- This file lives in gems/super_exception_notifier/rails/app/views/exception_notifiable/403.html. See Readme for instructions on customizing. -->
|
2
|
+
<div class="dialog">
|
3
|
+
<h1>Access Restricted</h1>
|
4
|
+
|
5
|
+
<p>If you need access to this resource please contact support or an administrator.</p>
|
6
|
+
</div>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<!-- This file lives in gems/super_exception_notifier/rails/app/views/exception_notifiable/404.html. See Readme for instructions on customizing. -->
|
2
|
+
<div class="dialog">
|
3
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
4
|
+
|
5
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
6
|
+
</div>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<!-- This file lives in gems/super_exception_notifier/rails/app/views/exception_notifiable/410.html. See Readme for instructions on customizing. -->
|
2
|
+
<div class="dialog">
|
3
|
+
<h1>Requested resource is no longer available</h1>
|
4
|
+
|
5
|
+
<p>Please remove bookmarks to this resource.</p>
|
6
|
+
<p>If you arrived here via a link from somewhere else please inform them of the broken link.</p>
|
7
|
+
</div>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<!-- This file lives in gems/super_exception_notifier/rails/app/views/exception_notifiable/418.html. See Readme for instructions on customizing. -->
|
2
|
+
<div class="dialog">
|
3
|
+
<h1>418 I�m a teapot</h1>
|
4
|
+
|
5
|
+
<p>I MAY be short and stout. Defined by the April Fools specification RFC 2324. See Hyper Text Coffee Pot Control Protocol for more information.</p>
|
6
|
+
</div>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<!-- This file lives in gems/super_exception_notifier/rails/app/views/exception_notifiable/422.html. See Readme for instructions on customizing. -->
|
2
|
+
<div class="dialog">
|
3
|
+
<h1>Unprocessable Request</h1>
|
4
|
+
<p>The request was well-formed but was unable to be followed due to semantic errors.</p>
|
5
|
+
</div>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<!-- This file lives in gems/super_exception_notifier/rails/app/views/exception_notifiable/423.html. See Readme for instructions on customizing. -->
|
2
|
+
<div class="dialog">
|
3
|
+
<h1>The change you wanted was rejected because the resource is locked</h1>
|
4
|
+
<p>It might become available again soon, if you try again!</p>
|
5
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
6
|
+
</div>
|