bmpercy-exception_notification 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +21 -0
- data/README.rdoc +539 -0
- data/VERSION.yml +5 -0
- data/init.rb +1 -0
- data/lib/exception_notifiable.rb +177 -0
- data/lib/exception_notifier.rb +176 -0
- data/lib/exception_notifier_helper.rb +60 -0
- data/lib/notifiable.rb +92 -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 +80 -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
- data/views/exception_notifier/rake_exception_notification.text.plain.erb +6 -0
- metadata +132 -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,80 @@
|
|
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, rejected_sections = 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
|
+
puts "[SECTIONS] #{ExceptionNotifier.sections_for_email(rejected_sections, request)}"
|
42
|
+
req = request ? " for request_uri=#{request.request_uri} and env=#{request.env.inspect}" : ""
|
43
|
+
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?
|
44
|
+
end
|
45
|
+
|
46
|
+
def perform_exception_notify_mailing(exception, data, request = nil, the_blamed = nil, verbose = false, rejected_sections = nil)
|
47
|
+
if ExceptionNotifier.config[:exception_recipients].blank?
|
48
|
+
puts "[EMAIL NOTIFICATION] ExceptionNotifier.config[:exception_recipients] is blank, notification cancelled!" if verbose
|
49
|
+
else
|
50
|
+
class_name = self.respond_to?(:controller_name) ? self.controller_name : self.to_s
|
51
|
+
method_name = self.respond_to?(:action_name) ? self.action_name : get_method_name
|
52
|
+
ExceptionNotifier.deliver_exception_notification(exception, class_name, method_name,
|
53
|
+
request, data, the_blamed, rejected_sections)
|
54
|
+
puts "[EMAIL NOTIFICATION] Sent" if verbose
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def should_email_on_exception?(exception, status_cd = nil, verbose = false)
|
59
|
+
notification_level_sends_email? && !ExceptionNotifier.config[:exception_recipients].empty? && should_notify_on_exception?(exception, status_cd, verbose)
|
60
|
+
end
|
61
|
+
|
62
|
+
def should_web_hook_on_exception?(exception, status_cd = nil, verbose = false)
|
63
|
+
notification_level_sends_web_hooks? && !ExceptionNotifier.config[:web_hooks].empty? && should_notify_on_exception?(exception, status_cd, verbose)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Relies on the base class to define be_silent_for_exception?
|
67
|
+
def should_notify_on_exception?(exception, status_cd = nil, verbose = false)
|
68
|
+
# don't notify (email or web hooks) on exceptions raised locally
|
69
|
+
verbose && ExceptionNotifier.config[:skip_local_notification] && is_local? ?
|
70
|
+
"[NOTIFY LOCALLY] NO" :
|
71
|
+
nil
|
72
|
+
return false if ExceptionNotifier.config[:skip_local_notification] && is_local?
|
73
|
+
# don't notify (email or web hooks) exceptions raised that match ExceptionNotifiable.notifiable_silent_exceptions
|
74
|
+
return false if self.be_silent_for_exception?(exception)
|
75
|
+
return true if ExceptionNotifier.config[:notify_error_classes].include?(exception.class)
|
76
|
+
return true if !status_cd.nil? && ExceptionNotifier.config[:notify_error_codes].include?(status_cd)
|
77
|
+
return ExceptionNotifier.config[:notify_other_errors]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
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>
|