exceptron 0.0.2
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 +20 -0
- data/README.rdoc +3 -0
- data/lib/exceptron.rb +38 -0
- data/lib/exceptron/dispatcher.rb +58 -0
- data/lib/exceptron/exception.rb +97 -0
- data/lib/exceptron/exceptions_controller.rb +19 -0
- data/lib/exceptron/helpers.rb +24 -0
- data/lib/exceptron/local_exceptions_controller.rb +17 -0
- data/lib/exceptron/local_helpers.rb +27 -0
- data/lib/exceptron/middleware.rb +27 -0
- data/lib/exceptron/railtie.rb +16 -0
- data/lib/exceptron/version.rb +3 -0
- data/lib/exceptron/views/exceptron/exceptions/internal_server_error.html.erb +26 -0
- data/lib/exceptron/views/exceptron/local_exceptions/_request_and_response.erb +27 -0
- data/lib/exceptron/views/exceptron/local_exceptions/_trace.erb +26 -0
- data/lib/exceptron/views/exceptron/local_exceptions/diagnostics.erb +10 -0
- data/lib/exceptron/views/exceptron/local_exceptions/missing_template.erb +2 -0
- data/lib/exceptron/views/exceptron/local_exceptions/routing_error.erb +10 -0
- data/lib/exceptron/views/exceptron/local_exceptions/template_error.erb +17 -0
- data/lib/exceptron/views/exceptron/local_exceptions/unknown_action.erb +2 -0
- data/lib/exceptron/views/layouts/exceptron/local_exceptions.erb +31 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/controllers/application_controller.rb +4 -0
- data/test/dummy/app/controllers/exceptions_controller.rb +24 -0
- data/test/dummy/app/controllers/home_controller.rb +4 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/app_exceptions/internal_server_error.html.erb +2 -0
- data/test/dummy/app/views/app_exceptions/not_found.html.erb +2 -0
- data/test/dummy/app/views/home/index.erb +1 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/layouts/exceptions.html.erb +12 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +49 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +22 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +25 -0
- data/test/dummy/config/environments/production.rb +49 -0
- data/test/dummy/config/environments/test.rb +35 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +60 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/production.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +15 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +40506 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/javascripts/application.js +2 -0
- data/test/dummy/public/javascripts/controls.js +965 -0
- data/test/dummy/public/javascripts/dragdrop.js +974 -0
- data/test/dummy/public/javascripts/effects.js +1123 -0
- data/test/dummy/public/javascripts/prototype.js +4874 -0
- data/test/dummy/public/javascripts/rails.js +118 -0
- data/test/dummy/public/stylesheets/exceptions.css +17 -0
- data/test/dummy/script/rails +6 -0
- data/test/exceptron_local_custom_test.rb +173 -0
- data/test/exceptron_local_test.rb +122 -0
- data/test/exceptron_public_custom_test.rb +128 -0
- data/test/exceptron_public_test.rb +72 -0
- data/test/test_helper.rb +48 -0
- data/test/views/exceptions_custom/internal_server_error.da.html.erb +1 -0
- data/test/views/exceptions_custom/internal_server_error.json +1 -0
- data/test/views/exceptions_custom/not_found.html +26 -0
- data/test/views/exceptions_custom/not_found.xml +5 -0
- data/test/views/exceptions_custom/not_implemented.html.erb +26 -0
- data/test/views/layouts/exception_test.html.erb +12 -0
- data/test/views/local_exceptions_custom/diagnostics.da.html.erb +1 -0
- data/test/views/local_exceptions_custom/not_implemented.html.erb +26 -0
- data/test/views/local_exceptions_custom/unknown_action.erb +2 -0
- metadata +197 -0
@@ -0,0 +1,118 @@
|
|
1
|
+
document.observe("dom:loaded", function() {
|
2
|
+
function handleRemote(element) {
|
3
|
+
var method, url, params;
|
4
|
+
|
5
|
+
if (element.tagName.toLowerCase() === 'form') {
|
6
|
+
method = element.readAttribute('method') || 'post';
|
7
|
+
url = element.readAttribute('action');
|
8
|
+
params = element.serialize(true);
|
9
|
+
} else {
|
10
|
+
method = element.readAttribute('data-method') || 'get';
|
11
|
+
url = element.readAttribute('href');
|
12
|
+
params = {};
|
13
|
+
}
|
14
|
+
|
15
|
+
var event = element.fire("ajax:before");
|
16
|
+
if (event.stopped) return false;
|
17
|
+
|
18
|
+
new Ajax.Request(url, {
|
19
|
+
method: method,
|
20
|
+
parameters: params,
|
21
|
+
asynchronous: true,
|
22
|
+
evalScripts: true,
|
23
|
+
|
24
|
+
onLoading: function(request) { element.fire("ajax:loading", {request: request}); },
|
25
|
+
onLoaded: function(request) { element.fire("ajax:loaded", {request: request}); },
|
26
|
+
onInteractive: function(request) { element.fire("ajax:interactive", {request: request}); },
|
27
|
+
onComplete: function(request) { element.fire("ajax:complete", {request: request}); },
|
28
|
+
onSuccess: function(request) { element.fire("ajax:success", {request: request}); },
|
29
|
+
onFailure: function(request) { element.fire("ajax:failure", {request: request}); }
|
30
|
+
});
|
31
|
+
|
32
|
+
element.fire("ajax:after");
|
33
|
+
}
|
34
|
+
|
35
|
+
function handleMethod(element) {
|
36
|
+
var method, url, token_name, token;
|
37
|
+
|
38
|
+
method = element.readAttribute('data-method');
|
39
|
+
url = element.readAttribute('href');
|
40
|
+
csrf_param = $$('meta[name=csrf-param]').first();
|
41
|
+
csrf_token = $$('meta[name=csrf-token]').first();
|
42
|
+
|
43
|
+
var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
|
44
|
+
element.parentNode.appendChild(form);
|
45
|
+
|
46
|
+
if (method != 'post') {
|
47
|
+
var field = new Element('input', { type: 'hidden', name: '_method', value: method });
|
48
|
+
form.appendChild(field);
|
49
|
+
}
|
50
|
+
|
51
|
+
if (csrf_param) {
|
52
|
+
var param = csrf_param.readAttribute('content');
|
53
|
+
var token = csrf_token.readAttribute('content');
|
54
|
+
var field = new Element('input', { type: 'hidden', name: param, value: token });
|
55
|
+
form.appendChild(field);
|
56
|
+
}
|
57
|
+
|
58
|
+
form.submit();
|
59
|
+
}
|
60
|
+
|
61
|
+
$(document.body).observe("click", function(event) {
|
62
|
+
var message = event.findElement().readAttribute('data-confirm');
|
63
|
+
if (message && !confirm(message)) {
|
64
|
+
event.stop();
|
65
|
+
return false;
|
66
|
+
}
|
67
|
+
|
68
|
+
var element = event.findElement("a[data-remote]");
|
69
|
+
if (element) {
|
70
|
+
handleRemote(element);
|
71
|
+
event.stop();
|
72
|
+
return true;
|
73
|
+
}
|
74
|
+
|
75
|
+
var element = event.findElement("a[data-method]");
|
76
|
+
if (element) {
|
77
|
+
handleMethod(element);
|
78
|
+
event.stop();
|
79
|
+
return true;
|
80
|
+
}
|
81
|
+
});
|
82
|
+
|
83
|
+
// TODO: I don't think submit bubbles in IE
|
84
|
+
$(document.body).observe("submit", function(event) {
|
85
|
+
var element = event.findElement(),
|
86
|
+
message = element.readAttribute('data-confirm');
|
87
|
+
if (message && !confirm(message)) {
|
88
|
+
event.stop();
|
89
|
+
return false;
|
90
|
+
}
|
91
|
+
|
92
|
+
var inputs = element.select("input[type=submit][data-disable-with]");
|
93
|
+
inputs.each(function(input) {
|
94
|
+
input.disabled = true;
|
95
|
+
input.writeAttribute('data-original-value', input.value);
|
96
|
+
input.value = input.readAttribute('data-disable-with');
|
97
|
+
});
|
98
|
+
|
99
|
+
var element = event.findElement("form[data-remote]");
|
100
|
+
if (element) {
|
101
|
+
handleRemote(element);
|
102
|
+
event.stop();
|
103
|
+
}
|
104
|
+
});
|
105
|
+
|
106
|
+
$(document.body).observe("ajax:after", function(event) {
|
107
|
+
var element = event.findElement();
|
108
|
+
|
109
|
+
if (element.tagName.toLowerCase() === 'form') {
|
110
|
+
var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
|
111
|
+
inputs.each(function(input) {
|
112
|
+
input.value = input.readAttribute('data-original-value');
|
113
|
+
input.writeAttribute('data-original-value', null);
|
114
|
+
input.disabled = false;
|
115
|
+
});
|
116
|
+
}
|
117
|
+
});
|
118
|
+
});
|
@@ -0,0 +1,17 @@
|
|
1
|
+
body {
|
2
|
+
background-color: #fff;
|
3
|
+
color: #666;
|
4
|
+
text-align: center;
|
5
|
+
font-family: arial, sans-serif;
|
6
|
+
}
|
7
|
+
|
8
|
+
div.dialog {
|
9
|
+
width: 25em;
|
10
|
+
padding: 0 4em;
|
11
|
+
margin: 4em auto 0 auto;
|
12
|
+
border: 1px solid #ccc;
|
13
|
+
border-right-color: #999;
|
14
|
+
border-bottom-color: #999;
|
15
|
+
}
|
16
|
+
|
17
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ExceptronLocalCustomTest < ActionDispatch::IntegrationTest
|
4
|
+
def setup
|
5
|
+
# Hack to test inherited hook
|
6
|
+
klass = Class.new(Exceptron::LocalExceptionsController) do
|
7
|
+
def self.name
|
8
|
+
'LocalExceptionsCustomController'
|
9
|
+
end
|
10
|
+
|
11
|
+
prepend_view_path File.expand_path('../views', __FILE__)
|
12
|
+
|
13
|
+
def internal_server_error
|
14
|
+
respond_to do |format|
|
15
|
+
format.html { super }
|
16
|
+
format.json { render :json => exception_presenter.to_json }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def not_found
|
21
|
+
respond_to do |format|
|
22
|
+
format.html { render :action => Exceptron.rescue_templates[exception_presenter.original_exception.class.name] }
|
23
|
+
format.xml { render :xml => exception_presenter.to_xml }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Object.const_set klass.name, klass
|
29
|
+
end
|
30
|
+
|
31
|
+
def teardown
|
32
|
+
Object.send :remove_const, 'LocalExceptionsCustomController'
|
33
|
+
Exceptron.local_controller = Exceptron::LocalExceptionsController
|
34
|
+
end
|
35
|
+
|
36
|
+
test "rescue locally from a local request" do
|
37
|
+
@app = ProductionApp
|
38
|
+
['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address|
|
39
|
+
self.remote_addr = ip_address
|
40
|
+
|
41
|
+
get "/"
|
42
|
+
assert_response 500
|
43
|
+
assert_equal 'text/html', response.content_type.to_s
|
44
|
+
assert_select 'title', "Exceptron: Exception caught"
|
45
|
+
assert_select 'body' do
|
46
|
+
assert_select 'h1', "RuntimeError"
|
47
|
+
end
|
48
|
+
assert_match(/puke/, body)
|
49
|
+
|
50
|
+
get "/not_found"
|
51
|
+
assert_response 404
|
52
|
+
assert_equal 'text/html', response.content_type.to_s
|
53
|
+
assert_select 'title', "Exceptron: Exception caught"
|
54
|
+
assert_select 'body' do
|
55
|
+
assert_select 'h1', "[CUSTOM] Unknown action"
|
56
|
+
assert_select 'p', "[CUSTOM] AbstractController::ActionNotFound"
|
57
|
+
end
|
58
|
+
|
59
|
+
get "/method_not_allowed"
|
60
|
+
assert_response 405
|
61
|
+
assert_equal 'text/html', response.content_type.to_s
|
62
|
+
assert_select 'title', "Exceptron: Exception caught"
|
63
|
+
assert_select 'body' do
|
64
|
+
assert_select 'h1', "ActionController::MethodNotAllowed"
|
65
|
+
end
|
66
|
+
|
67
|
+
get "/not_implemented"
|
68
|
+
assert_response 501
|
69
|
+
assert_equal 'text/html', response.content_type.to_s
|
70
|
+
assert_select 'title', "[CUSTOM] 501 Not Implemented"
|
71
|
+
assert_select 'body' do
|
72
|
+
assert_select 'h1', "[CUSTOM] 501 Not Implemented"
|
73
|
+
assert_select 'p', "[CUSTOM] 501 Not Implemented"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
test "always rescue locally in development mode" do
|
79
|
+
@app = DevelopmentApp
|
80
|
+
self.remote_addr = '208.77.188.166'
|
81
|
+
|
82
|
+
get "/"
|
83
|
+
assert_response 500
|
84
|
+
assert_equal 'text/html', response.content_type.to_s
|
85
|
+
assert_select 'title', "Exceptron: Exception caught"
|
86
|
+
assert_select 'body' do
|
87
|
+
assert_select 'h1', "RuntimeError"
|
88
|
+
end
|
89
|
+
assert_match(/puke/, body)
|
90
|
+
|
91
|
+
get "/not_found"
|
92
|
+
assert_response 404
|
93
|
+
assert_equal 'text/html', response.content_type.to_s
|
94
|
+
assert_select 'title', "Exceptron: Exception caught"
|
95
|
+
assert_select 'body' do
|
96
|
+
assert_select 'h1', "[CUSTOM] Unknown action"
|
97
|
+
assert_select 'p', "[CUSTOM] AbstractController::ActionNotFound"
|
98
|
+
end
|
99
|
+
|
100
|
+
get "/method_not_allowed"
|
101
|
+
assert_response 405
|
102
|
+
assert_equal 'text/html', response.content_type.to_s
|
103
|
+
assert_select 'title', "Exceptron: Exception caught"
|
104
|
+
assert_select 'body' do
|
105
|
+
assert_select 'h1', "ActionController::MethodNotAllowed"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
test "localize public rescue message" do
|
110
|
+
old_locale, I18n.locale = I18n.locale, :da
|
111
|
+
|
112
|
+
begin
|
113
|
+
@app = DevelopmentApp
|
114
|
+
|
115
|
+
get "/"
|
116
|
+
assert_response 500
|
117
|
+
assert_equal 'text/html', response.content_type.to_s
|
118
|
+
assert_match /500 localized error fixture/, body
|
119
|
+
|
120
|
+
get "/not_found"
|
121
|
+
assert_response 404
|
122
|
+
assert_equal 'text/html', response.content_type.to_s
|
123
|
+
assert_select 'title', "Exceptron: Exception caught"
|
124
|
+
assert_select 'body' do
|
125
|
+
assert_select 'h1', "[CUSTOM] Unknown action"
|
126
|
+
assert_select 'p', "[CUSTOM] AbstractController::ActionNotFound"
|
127
|
+
end
|
128
|
+
ensure
|
129
|
+
I18n.locale = old_locale
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
test "does not show filtered parameters" do
|
134
|
+
@app = DevelopmentApp
|
135
|
+
|
136
|
+
get "/", {"foo"=>"bar"}, { 'action_dispatch.parameter_filter' => [:foo] }
|
137
|
+
assert_response 500
|
138
|
+
assert_equal 'text/html', response.content_type.to_s
|
139
|
+
assert_match(""foo"=>"[FILTERED]"", body)
|
140
|
+
end
|
141
|
+
|
142
|
+
test "show registered original exception for wrapped exceptions when consider_all_requests_local is true" do
|
143
|
+
@app = DevelopmentApp
|
144
|
+
|
145
|
+
get "/not_found_original_exception"
|
146
|
+
assert_response 404
|
147
|
+
assert_select 'title', "Exceptron: Exception caught"
|
148
|
+
assert_equal 'text/html', response.content_type.to_s
|
149
|
+
assert_select 'body' do
|
150
|
+
assert_select 'h1', "[CUSTOM] Unknown action"
|
151
|
+
assert_select 'p', "[CUSTOM] AbstractController::ActionNotFound"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
test "rescue other formats in public from a remote ip" do
|
156
|
+
@app = ProductionApp
|
157
|
+
['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address|
|
158
|
+
self.remote_addr = ip_address
|
159
|
+
|
160
|
+
get "/", {}, 'HTTP_ACCEPT' => 'application/json'
|
161
|
+
assert_response 500
|
162
|
+
assert_equal 'application/json', response.content_type.to_s
|
163
|
+
assert_match %r{"message":"Internal Server Error"}, response.body
|
164
|
+
assert_match %r{"status":500}, response.body
|
165
|
+
|
166
|
+
get "/not_found", {}, 'HTTP_ACCEPT' => 'application/xml'
|
167
|
+
assert_response 404
|
168
|
+
assert_equal 'application/xml', response.content_type.to_s
|
169
|
+
assert_match %r{<message>Not Found</message>}, response.body
|
170
|
+
assert_match %r{<status type="integer">404</status>}, response.body
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ExceptronLocalTest < ActionDispatch::IntegrationTest
|
4
|
+
test "rescue locally from a local request" do
|
5
|
+
@app = ProductionApp
|
6
|
+
['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address|
|
7
|
+
self.remote_addr = ip_address
|
8
|
+
|
9
|
+
get "/"
|
10
|
+
assert_response 500
|
11
|
+
assert_equal 'text/html', response.content_type.to_s
|
12
|
+
assert_select 'title', "Exceptron: Exception caught"
|
13
|
+
assert_select 'body' do
|
14
|
+
assert_select 'h1', "RuntimeError"
|
15
|
+
end
|
16
|
+
assert_match(/puke/, body)
|
17
|
+
|
18
|
+
get "/not_found"
|
19
|
+
assert_response 404
|
20
|
+
assert_equal 'text/html', response.content_type.to_s
|
21
|
+
assert_select 'title', "Exceptron: Exception caught"
|
22
|
+
assert_select 'body' do
|
23
|
+
assert_select 'h1', "Unknown action"
|
24
|
+
assert_select 'p', "AbstractController::ActionNotFound"
|
25
|
+
end
|
26
|
+
|
27
|
+
get "/method_not_allowed"
|
28
|
+
assert_response 405
|
29
|
+
assert_equal 'text/html', response.content_type.to_s
|
30
|
+
assert_select 'title', "Exceptron: Exception caught"
|
31
|
+
assert_select 'body' do
|
32
|
+
assert_select 'h1', "ActionController::MethodNotAllowed"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
test "always rescue locally in development mode" do
|
38
|
+
@app = DevelopmentApp
|
39
|
+
self.remote_addr = '208.77.188.166'
|
40
|
+
|
41
|
+
get "/"
|
42
|
+
assert_response 500
|
43
|
+
assert_equal 'text/html', response.content_type.to_s
|
44
|
+
assert_select 'title', "Exceptron: Exception caught"
|
45
|
+
assert_select 'body' do
|
46
|
+
assert_select 'h1', "RuntimeError"
|
47
|
+
end
|
48
|
+
assert_match(/puke/, body)
|
49
|
+
|
50
|
+
get "/not_found"
|
51
|
+
assert_response 404
|
52
|
+
assert_equal 'text/html', response.content_type.to_s
|
53
|
+
assert_select 'title', "Exceptron: Exception caught"
|
54
|
+
assert_select 'body' do
|
55
|
+
assert_select 'h1', "Unknown action"
|
56
|
+
assert_select 'p', "AbstractController::ActionNotFound"
|
57
|
+
end
|
58
|
+
|
59
|
+
get "/method_not_allowed"
|
60
|
+
assert_response 405
|
61
|
+
assert_equal 'text/html', response.content_type.to_s
|
62
|
+
assert_select 'title', "Exceptron: Exception caught"
|
63
|
+
assert_select 'body' do
|
64
|
+
assert_select 'h1', "ActionController::MethodNotAllowed"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
test "does not show filtered parameters" do
|
69
|
+
@app = DevelopmentApp
|
70
|
+
|
71
|
+
get "/", {"foo"=>"bar"}, { 'action_dispatch.parameter_filter' => [:foo] }
|
72
|
+
assert_response 500
|
73
|
+
assert_equal 'text/html', response.content_type.to_s
|
74
|
+
assert_match(""foo"=>"[FILTERED]"", body)
|
75
|
+
end
|
76
|
+
|
77
|
+
test "show registered original exception for wrapped exceptions when consider_all_requests_local is true" do
|
78
|
+
@app = DevelopmentApp
|
79
|
+
|
80
|
+
get "/not_found_original_exception"
|
81
|
+
assert_response 404
|
82
|
+
assert_select 'title', "Exceptron: Exception caught"
|
83
|
+
assert_equal 'text/html', response.content_type.to_s
|
84
|
+
assert_select 'body' do
|
85
|
+
assert_select 'h1', "Unknown action"
|
86
|
+
assert_select 'p', "AbstractController::ActionNotFound"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
test "rescue locally other formats as html from a local request" do
|
91
|
+
@app = ProductionApp
|
92
|
+
['127.0.0.1', '127.0.0.127', '::1', '0:0:0:0:0:0:0:1', '0:0:0:0:0:0:0:1%0'].each do |ip_address|
|
93
|
+
self.remote_addr = ip_address
|
94
|
+
|
95
|
+
get "/", {}, 'HTTP_ACCEPT' => 'application/json'
|
96
|
+
assert_response 500
|
97
|
+
assert_equal 'text/html', response.content_type.to_s
|
98
|
+
assert_select 'title', "Exceptron: Exception caught"
|
99
|
+
assert_select 'body' do
|
100
|
+
assert_select 'h1', "RuntimeError"
|
101
|
+
end
|
102
|
+
assert_match(/puke/, body)
|
103
|
+
|
104
|
+
get "/not_found", {}, 'HTTP_ACCEPT' => 'application/xml'
|
105
|
+
assert_response 404
|
106
|
+
assert_equal 'text/html', response.content_type.to_s
|
107
|
+
assert_select 'title', "Exceptron: Exception caught"
|
108
|
+
assert_select 'body' do
|
109
|
+
assert_select 'h1', "Unknown action"
|
110
|
+
assert_select 'p', "AbstractController::ActionNotFound"
|
111
|
+
end
|
112
|
+
|
113
|
+
get "/method_not_allowed", {}, 'HTTP_ACCEPT' => 'application/json'
|
114
|
+
assert_response 405
|
115
|
+
assert_equal 'text/html', response.content_type.to_s
|
116
|
+
assert_select 'title', "Exceptron: Exception caught"
|
117
|
+
assert_select 'body' do
|
118
|
+
assert_select 'h1', "ActionController::MethodNotAllowed"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ExceptronPublicCustomTest < ActionDispatch::IntegrationTest
|
4
|
+
def setup
|
5
|
+
# Hack to test inherited hook
|
6
|
+
klass = Class.new(Exceptron::ExceptionsController) do
|
7
|
+
def self.name
|
8
|
+
'ExceptionsCustomController'
|
9
|
+
end
|
10
|
+
|
11
|
+
prepend_view_path File.expand_path('../views', __FILE__)
|
12
|
+
end
|
13
|
+
|
14
|
+
Object.const_set klass.name, klass
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
Object.send :remove_const, 'ExceptionsCustomController'
|
19
|
+
Exceptron.controller = Exceptron::ExceptionsController
|
20
|
+
end
|
21
|
+
|
22
|
+
test "rescue in public from a remote ip" do
|
23
|
+
@app = ProductionApp
|
24
|
+
self.remote_addr = '208.77.188.166'
|
25
|
+
|
26
|
+
get "/"
|
27
|
+
assert_response 500
|
28
|
+
assert_equal 'text/html', response.content_type.to_s
|
29
|
+
assert_select 'title', "We're sorry, but something went wrong (500)"
|
30
|
+
assert_select 'body' do
|
31
|
+
assert_select 'h1', "We're sorry, but something went wrong."
|
32
|
+
assert_select 'p', "We've been notified about this issue and we'll take a look at it shortly."
|
33
|
+
end
|
34
|
+
|
35
|
+
get "/not_found"
|
36
|
+
assert_response 404
|
37
|
+
assert_equal 'text/html', response.content_type.to_s
|
38
|
+
assert_select 'title', "[CUSTOM] The page you were looking for doesn't exist (404)"
|
39
|
+
assert_select 'body' do
|
40
|
+
assert_select 'h1', "[CUSTOM] The page you were looking for doesn't exist."
|
41
|
+
assert_select 'p', "[CUSTOM] You may have mistyped the address or the page may have moved."
|
42
|
+
end
|
43
|
+
|
44
|
+
get "/method_not_allowed"
|
45
|
+
assert_response 405
|
46
|
+
assert_equal 'text/html', response.content_type.to_s
|
47
|
+
assert_select 'title', "We're sorry, but something went wrong (405)"
|
48
|
+
assert_select 'body' do
|
49
|
+
assert_select 'h1', "We're sorry, but something went wrong."
|
50
|
+
assert_select 'p', "We've been notified about this issue and we'll take a look at it shortly."
|
51
|
+
end
|
52
|
+
|
53
|
+
get "/not_implemented"
|
54
|
+
assert_response 501
|
55
|
+
assert_equal 'text/html', response.content_type.to_s
|
56
|
+
assert_select 'title', "[CUSTOM] 501 Not Implemented"
|
57
|
+
assert_select 'body' do
|
58
|
+
assert_select 'h1', "[CUSTOM] 501 Not Implemented"
|
59
|
+
assert_select 'p', "[CUSTOM] 501 Not Implemented"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
test "localize public rescue message" do
|
64
|
+
old_locale, I18n.locale = I18n.locale, :da
|
65
|
+
|
66
|
+
begin
|
67
|
+
@app = ProductionApp
|
68
|
+
self.remote_addr = '208.77.188.166'
|
69
|
+
|
70
|
+
get "/"
|
71
|
+
assert_response 500
|
72
|
+
assert_equal 'text/html', response.content_type.to_s
|
73
|
+
assert_match /500 localized error fixture/, body
|
74
|
+
|
75
|
+
get "/not_found"
|
76
|
+
assert_response 404
|
77
|
+
assert_equal 'text/html', response.content_type.to_s
|
78
|
+
assert_select 'title', "[CUSTOM] The page you were looking for doesn't exist (404)"
|
79
|
+
assert_select 'body' do
|
80
|
+
assert_select 'h1', "[CUSTOM] The page you were looking for doesn't exist."
|
81
|
+
assert_select 'p', "[CUSTOM] You may have mistyped the address or the page may have moved."
|
82
|
+
end
|
83
|
+
ensure
|
84
|
+
I18n.locale = old_locale
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
test "does not show filtered parameters" do
|
89
|
+
@app = ProductionApp
|
90
|
+
self.remote_addr = '208.77.188.166'
|
91
|
+
|
92
|
+
get "/not_implemented", {"foo"=>"bar"}, { 'action_dispatch.parameter_filter' => [:foo] }
|
93
|
+
assert_response 501
|
94
|
+
assert_equal 'text/html', response.content_type.to_s
|
95
|
+
assert_match(""foo"=>"[FILTERED]"", body)
|
96
|
+
end
|
97
|
+
|
98
|
+
test "show registered original exception for wrapped exceptions when consider_all_requests_local is false" do
|
99
|
+
@app = ProductionApp
|
100
|
+
self.remote_addr = '208.77.188.166'
|
101
|
+
|
102
|
+
get "/not_found_original_exception"
|
103
|
+
assert_response 404
|
104
|
+
assert_equal 'text/html', response.content_type.to_s
|
105
|
+
assert_select 'title', "[CUSTOM] The page you were looking for doesn't exist (404)"
|
106
|
+
assert_select 'body' do
|
107
|
+
assert_select 'h1', "[CUSTOM] The page you were looking for doesn't exist."
|
108
|
+
assert_select 'p', "[CUSTOM] You may have mistyped the address or the page may have moved."
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
test "rescue other formats in public from a remote ip" do
|
113
|
+
@app = ProductionApp
|
114
|
+
self.remote_addr = '208.77.188.166'
|
115
|
+
|
116
|
+
get "/", {}, 'HTTP_ACCEPT' => 'application/json'
|
117
|
+
assert_response 500
|
118
|
+
assert_equal 'application/json', response.content_type.to_s
|
119
|
+
assert_match %r{"message":"CUSTOM Internal Server Error"}, response.body
|
120
|
+
assert_match %r{"status":500}, response.body
|
121
|
+
|
122
|
+
get "/not_found", {}, 'HTTP_ACCEPT' => 'application/xml'
|
123
|
+
assert_response 404
|
124
|
+
assert_equal 'application/xml', response.content_type.to_s
|
125
|
+
assert_match %r{<message>CUSTOM Not Found</message>}, response.body
|
126
|
+
assert_match %r{<status type="integer">404</status>}, response.body
|
127
|
+
end
|
128
|
+
end
|