rails_dynamic_errors 0.0.9
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +31 -0
- data/app/controllers/rails_dynamic_errors/errors_controller.rb +52 -0
- data/app/views/rails_dynamic_errors/errors/show.html.erb +4 -0
- data/config/routes.rb +3 -0
- data/lib/engine_helper.rb +15 -0
- data/lib/generators/rails_dynamic_errors/install_generator.rb +38 -0
- data/lib/rails_dynamic_errors/engine.rb +32 -0
- data/lib/rails_dynamic_errors/middleware/dynamic_errors.rb +98 -0
- data/lib/rails_dynamic_errors/version.rb +4 -0
- data/lib/rails_dynamic_errors.rb +11 -0
- data/lib/tasks/rails_dynamic_errors_tasks.rake +4 -0
- data/spec/controllers/errors_controller_spec.rb +128 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/javascripts/booms.js +2 -0
- data/spec/dummy/app/assets/javascripts/things.js +2 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/assets/stylesheets/booms.css +4 -0
- data/spec/dummy/app/assets/stylesheets/scaffold.css +56 -0
- data/spec/dummy/app/assets/stylesheets/things.css +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/booms_controller.rb +6 -0
- data/spec/dummy/app/controllers/things_controller.rb +58 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/booms_helper.rb +2 -0
- data/spec/dummy/app/helpers/things_helper.rb +2 -0
- data/spec/dummy/app/models/thing.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/rails_dynamic_errors/errors/url_helpers.html.erb +2 -0
- data/spec/dummy/app/views/things/_form.html.erb +21 -0
- data/spec/dummy/app/views/things/edit.html.erb +6 -0
- data/spec/dummy/app/views/things/index.html.erb +27 -0
- data/spec/dummy/app/views/things/new.html.erb +5 -0
- data/spec/dummy/app/views/things/show.html.erb +9 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +43 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +67 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20140620101702_create_things.rb +9 -0
- data/spec/dummy/db/production.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +22 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +3309 -0
- data/spec/dummy/log/production.log +35 -0
- data/spec/dummy/log/test.log +30008 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/config/application.rb +11 -0
- data/spec/dummy/tmp/config/routes.rb +10 -0
- data/spec/features/application_link_helpers_spec.rb +14 -0
- data/spec/features/error_handling_spec.rb +167 -0
- data/spec/lib/generators/rails_dynamic_errors/install_generator_spec.rb +32 -0
- data/spec/lib/rails_dynamic_errors/engine_spec.rb +13 -0
- data/spec/lib/rails_dynamic_errors/middleware/dynamic_errors_spec.rb +171 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/support/error.rb +19 -0
- data/spec/views/errors/show.html.erb_spec.rb +24 -0
- metadata +265 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 16b89e0d32d1bf5e55c35f732034a97bc4443d4b
|
4
|
+
data.tar.gz: d552978f2ca013a1ca79bddce0bf6fd227beb0e3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c01f9844d85c46762d7a00e14ef1c34ced628defe8c1219684134978ff4ab67a5d9045ab51d052fd90e500c38c5b38436439a9708bbbb71153a2277bae2888d9
|
7
|
+
data.tar.gz: 64c7b2eff6e5eacbb1aadae09ca1494775debe001b836048269b6be0784708496bf95739534de49483aa6a4a95356ba1522f38d69569d74ae1ae6dadb040c559
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'RailsDynamicErrors'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
Bundler::GemHelper.install_tasks
|
18
|
+
|
19
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
20
|
+
load 'rails/tasks/engine.rake'
|
21
|
+
|
22
|
+
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
|
23
|
+
|
24
|
+
require 'rspec/core'
|
25
|
+
require 'rspec/core/rake_task'
|
26
|
+
|
27
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
28
|
+
|
29
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
30
|
+
|
31
|
+
task :default => :spec
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'action_dispatch/middleware/exception_wrapper'
|
2
|
+
|
3
|
+
module RailsDynamicErrors
|
4
|
+
class ErrorsController < ::ApplicationController
|
5
|
+
helper_method :error_code
|
6
|
+
helper_method :error_name
|
7
|
+
helper_method :error_message
|
8
|
+
|
9
|
+
def show
|
10
|
+
render template, layout: layout, status: status_code
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def error_code
|
15
|
+
# The route that leads to this controller is set up with a glob that
|
16
|
+
# maps to params[:code]. Unfortunately, because Rails memoizes request
|
17
|
+
# parameters, this mapped data is not available if we arrive in this
|
18
|
+
# controller after processing a request to a valid route but with a
|
19
|
+
# non-existent resource. Thankfully we can just take the same steps
|
20
|
+
# here as the glob anyway - extract the code from the path.
|
21
|
+
@error_code ||= env['PATH_INFO'][1..-1]
|
22
|
+
end
|
23
|
+
|
24
|
+
def error_name
|
25
|
+
@error_name ||= Rack::Utils::HTTP_STATUS_CODES.fetch(status_code.to_i, 'Internal Server Error')
|
26
|
+
end
|
27
|
+
|
28
|
+
def error_message
|
29
|
+
if exception && exception.message && exception.class.name != exception.message
|
30
|
+
@message ||= exception.message
|
31
|
+
else
|
32
|
+
@message ||= "An error has occurred. This site administrator has been notified of this issue. We apologise for any inconvenience."
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def exception
|
37
|
+
@exception ||= env['action_dispatch.exception']
|
38
|
+
end
|
39
|
+
|
40
|
+
def status_code
|
41
|
+
@status_code ||= (exception) ? ActionDispatch::ExceptionWrapper.new(env, exception).status_code.to_s : '500'
|
42
|
+
end
|
43
|
+
|
44
|
+
def layout
|
45
|
+
template_exists?('errors', 'layouts') ? 'errors' : 'application'
|
46
|
+
end
|
47
|
+
|
48
|
+
def template
|
49
|
+
template_exists?(error_code, 'rails_dynamic_errors/errors') ? error_code : 'show'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# This module contains utility methods designed for inclusion within Rails
|
2
|
+
# engines.
|
3
|
+
module EngineHelper
|
4
|
+
module ClassMethods
|
5
|
+
# Identifies the absolute path (i.e. '/' prefixed) at which an engine is
|
6
|
+
# mounted within its parent Rails application.
|
7
|
+
# @return [String] the mount path, or nil if not mounted
|
8
|
+
def mounted_at
|
9
|
+
route = Rails.application.routes.routes.detect do |route|
|
10
|
+
route.app == self
|
11
|
+
end
|
12
|
+
route && route.path.spec.to_s
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module RailsDynamicErrors
|
4
|
+
# This is a generator that is used to install rails_dynamic_errors into a
|
5
|
+
# Rails application. It runs all of the methods below.
|
6
|
+
class InstallGenerator < Rails::Generators::Base
|
7
|
+
# Add the gem configuration options to the Rails application's
|
8
|
+
# config/application.rb file. These are all disabled by default so as to
|
9
|
+
# cause minimum intrusion upon install.
|
10
|
+
def configure_application
|
11
|
+
application <<-APP
|
12
|
+
# This option is used to set the HTTP error codes for which
|
13
|
+
# rails_dynamic_errors will generate dynamic error pages. A good default
|
14
|
+
# setup is [404, 422], which will catch the two main errors (excluding the
|
15
|
+
# dreaded 500 Internal Server Error) for which Rails provides static HTML
|
16
|
+
# error pages.
|
17
|
+
# config.rails_dynamic_errors.http_error_status_codes_to_handle = [404, 422]
|
18
|
+
APP
|
19
|
+
end
|
20
|
+
|
21
|
+
# Add mounting of the gem's engine to the the Rails application's
|
22
|
+
# config/routes.rb file. The default mount path can be found in the
|
23
|
+
# documentation for the RailsDynamicErrors module.
|
24
|
+
def notify_about_routes
|
25
|
+
insert_into_file File.join('config', 'routes.rb'), :before => /^end/ do
|
26
|
+
%Q{
|
27
|
+
# This line mounts RailDynamicErrors' routes on the '/errors' path of your
|
28
|
+
# application. This means that any requests to URLs with this prefix in their
|
29
|
+
# path will go to RailsDynamicErrors for processing.
|
30
|
+
#
|
31
|
+
# If you would like to change where this engine is mounted, simply change the
|
32
|
+
# :at option to something different.
|
33
|
+
mount RailsDynamicErrors::Engine, at: '#{RailsDynamicErrors::DEFAULT_MOUNT_PATH}'
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'engine_helper'
|
2
|
+
|
3
|
+
module RailsDynamicErrors
|
4
|
+
# This is the engine that provides dynamic error page generation for
|
5
|
+
# rails_dynamic_errors. It is designed to be mounted at an appropriate route
|
6
|
+
# within the main application, permitting the handling of generic error URLs
|
7
|
+
# that map to this base route.
|
8
|
+
#
|
9
|
+
# It also adds a namespace for rails_dynamic_errors configuration options
|
10
|
+
# within the parent application. These are accessible as per standard Rails
|
11
|
+
# application configuration options via:
|
12
|
+
#
|
13
|
+
# Rails.application.config.rails_dynamic_errors
|
14
|
+
#
|
15
|
+
# End users should never use this engine directly. It is created automatically
|
16
|
+
# when the main application is run. An install generator is included which
|
17
|
+
# updates the config/routes.rb file of the main application to include the
|
18
|
+
# necessary code to mount the engine at a default route.
|
19
|
+
#
|
20
|
+
# Note: the engine is namespaced to 'RailsDynamicErrors'.
|
21
|
+
class Engine < ::Rails::Engine
|
22
|
+
extend EngineHelper::ClassMethods
|
23
|
+
|
24
|
+
# Add configuration options within namespace in the main application
|
25
|
+
config.rails_dynamic_errors = ActiveSupport::OrderedOptions.new
|
26
|
+
|
27
|
+
initializer "rails_dynamic_errors.install_middleware" do |app|
|
28
|
+
# Avoid inserting if already inserted?
|
29
|
+
app.middleware.use RailsDynamicErrors::DynamicErrors
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'action_dispatch/middleware/exception_wrapper'
|
2
|
+
|
3
|
+
module RailsDynamicErrors
|
4
|
+
# This is a Rack compatible middleware that implements the key functionality
|
5
|
+
# of the rails_dynamic_errors gem. It serves two roles:
|
6
|
+
# * intercept unhandled exceptions and error conditions from the Rail application it is inserted into
|
7
|
+
# * generate dynamic error pages for the exceptions and error conditions it is configured to
|
8
|
+
#
|
9
|
+
# The middleware is inserted into the Rails application's middleware stack
|
10
|
+
# automatically. As such, the end user should never need to use it directly.
|
11
|
+
#
|
12
|
+
# In order to avoid disrupting standard Rails functionality, this middleware
|
13
|
+
# respects the Rails exception handling related configuration options. As
|
14
|
+
# such, it will only process exceptions and error conditions if:
|
15
|
+
# * the request is not local (action_dispatch.show_detailed_exceptions is false)
|
16
|
+
# * the environment is set to display exceptions (rather than raise them)
|
17
|
+
#
|
18
|
+
# Configuration of which exceptions and error conditions to catch is done
|
19
|
+
# within the main Rails application's configuration, using an option set
|
20
|
+
# namespaced to rails_dynamic_errors. Specifically:
|
21
|
+
#
|
22
|
+
# Rails.application.config.rails_dynamic_errors.http_error_status_codes_to_handle
|
23
|
+
#
|
24
|
+
# This option must be an array of integer HTTP error status codes (404, etc.)
|
25
|
+
class DynamicErrors
|
26
|
+
# Initialize the middleware (standard Rack method)
|
27
|
+
def initialize(app)
|
28
|
+
@app = app
|
29
|
+
end
|
30
|
+
|
31
|
+
# Call the middleware (standard Rack method)
|
32
|
+
def call(env)
|
33
|
+
response = @app.call(env)
|
34
|
+
# 404 errors for unmatched routes aren't actually raised until
|
35
|
+
# ActionDispatch::DebugExceptions. If we're supposed to catch 404s and
|
36
|
+
# the application indicates there was no matching route, throw and
|
37
|
+
# handle a 404 generating exception
|
38
|
+
if can_process_exceptions?(env) && catch_not_found_error? && request_unhandled?(response)
|
39
|
+
raise ActionController::RoutingError.new("No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}")
|
40
|
+
else
|
41
|
+
response
|
42
|
+
end
|
43
|
+
rescue Exception => exception
|
44
|
+
if can_process_exceptions?(env)
|
45
|
+
process_exception(env, exception)
|
46
|
+
else
|
47
|
+
raise exception
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def can_process_exceptions?(env)
|
53
|
+
! env['action_dispatch.show_detailed_exceptions'] && env['action_dispatch.show_exceptions']
|
54
|
+
end
|
55
|
+
|
56
|
+
def catch_not_found_error?
|
57
|
+
can_handle_http_error_status_code?(404)
|
58
|
+
end
|
59
|
+
|
60
|
+
def can_handle_http_error_status_code?(status_code)
|
61
|
+
http_error_status_codes_to_handle.include?(status_code)
|
62
|
+
end
|
63
|
+
|
64
|
+
def http_error_status_codes_to_handle
|
65
|
+
Rails.application.config.rails_dynamic_errors.http_error_status_codes_to_handle || []
|
66
|
+
end
|
67
|
+
|
68
|
+
def request_unhandled?(response)
|
69
|
+
# Returned by Rails when no matching route was found
|
70
|
+
[404, {'X-Cascade' => 'pass'}, ['Not Found']] == response
|
71
|
+
end
|
72
|
+
|
73
|
+
def process_exception(env, exception)
|
74
|
+
status_code = exception_http_error_status_code(env, exception)
|
75
|
+
if can_handle_http_error_status_code?(status_code)
|
76
|
+
generate_dynamic_error_page(env, exception, status_code)
|
77
|
+
else
|
78
|
+
raise exception
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def exception_http_error_status_code(env, exception)
|
83
|
+
wrapper = ActionDispatch::ExceptionWrapper.new(env, exception)
|
84
|
+
wrapper.status_code
|
85
|
+
end
|
86
|
+
|
87
|
+
def generate_dynamic_error_page(env, exception, status_code)
|
88
|
+
env['PATH_INFO'] = dynamic_error_path(status_code)
|
89
|
+
env['action_dispatch.exception'] = exception
|
90
|
+
Rails.application.routes.call(env)
|
91
|
+
end
|
92
|
+
|
93
|
+
def dynamic_error_path(status_code)
|
94
|
+
# Error page routes need to reflect where the engine has been mounted
|
95
|
+
"#{RailsDynamicErrors::Engine.mounted_at}/#{status_code}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rails_dynamic_errors/middleware/dynamic_errors'
|
2
|
+
require 'generators/rails_dynamic_errors/install_generator'
|
3
|
+
|
4
|
+
# +RailsDynamicErrors+ is the root module for the rails_dynamic_errors gem. See
|
5
|
+
# the README for more information.
|
6
|
+
module RailsDynamicErrors
|
7
|
+
# The default mount point for the gem's engine
|
8
|
+
DEFAULT_MOUNT_PATH = '/errors'
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'rails_dynamic_errors/engine'
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RailsDynamicErrors::ErrorsController do
|
4
|
+
describe "GET show" do
|
5
|
+
before(:each) do
|
6
|
+
@error_code = 404
|
7
|
+
end
|
8
|
+
|
9
|
+
it "makes the error code available" do
|
10
|
+
build_environment_after_exception_for_status_code(@error_code)
|
11
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
12
|
+
controller.send(:error_code).should eq(@error_code.to_s)
|
13
|
+
end
|
14
|
+
|
15
|
+
context "makes a friendly error name available" do
|
16
|
+
context "when the status code is a valid HTTP status code" do
|
17
|
+
it "returns the name associated with that status code" do
|
18
|
+
build_environment_after_exception_for_status_code(@error_code)
|
19
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
20
|
+
controller.send(:error_name).should eq("Not Found")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when the status code is not a valid HTTP status code" do
|
25
|
+
it "returns 'Internal Server Error'" do
|
26
|
+
controller.env["PATH_INFO"] = "/my_error"
|
27
|
+
get :show, code: 'my_error', use_route: :rails_dynamic_errors
|
28
|
+
controller.send(:error_name).should eq("Internal Server Error")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "makes the exception associated with the error (if any) available" do
|
34
|
+
context "when the error was caused by an exception" do
|
35
|
+
it "returns the exception" do
|
36
|
+
build_environment_after_exception_for_status_code(@error_code)
|
37
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
38
|
+
controller.send(:exception).should eq(@exception)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when the error was not caused by an exception" do
|
43
|
+
it "returns nil" do
|
44
|
+
controller.env["PATH_INFO"] = "/#{@error_code}"
|
45
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
46
|
+
controller.send(:exception).should eq(nil)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "makes an error message available" do
|
52
|
+
context "when the error was caused by an exception and that exception has a message" do
|
53
|
+
it "renders that error message" do
|
54
|
+
build_environment_after_exception_for_status_code(@error_code)
|
55
|
+
@exception.stub(:message).and_return("Test")
|
56
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
57
|
+
controller.send(:error_message).should eq(@exception.message)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when the error was not caused by an exception or was but the exception doesn't have a message" do
|
62
|
+
it "renders a default error message" do
|
63
|
+
build_environment_after_exception_for_status_code(@error_code)
|
64
|
+
@exception.stub(:message).and_return(nil)
|
65
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
66
|
+
controller.send(:error_message).should eq("An error has occurred. This site administrator has been notified of this issue. We apologise for any inconvenience.")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "renders an appropriate layout" do
|
72
|
+
before(:each) do
|
73
|
+
controller.stub(:template).and_return("show")
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when a custom error layout is available" do
|
77
|
+
it "uses the custom error layout" do
|
78
|
+
build_environment_after_exception_for_status_code(@error_code)
|
79
|
+
controller.stub(:layout).and_return("errors")
|
80
|
+
begin
|
81
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
82
|
+
response.should render_template("layouts/errors")
|
83
|
+
rescue ActionView::MissingTemplate => exception
|
84
|
+
exception.message.should =~ /Missing template layouts\/errors/
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "when a custom error layout is not available" do
|
90
|
+
it "uses the application layout" do
|
91
|
+
build_environment_after_exception_for_status_code(@error_code)
|
92
|
+
controller.stub(:layout).and_return("application")
|
93
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
94
|
+
response.should render_template("layouts/application")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "renders an appropriate template" do
|
100
|
+
before(:each) do
|
101
|
+
controller.stub(:layout).and_return("application")
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when a custom error template is available" do
|
105
|
+
it "uses the custom error template" do
|
106
|
+
build_environment_after_exception_for_status_code(@error_code)
|
107
|
+
controller.stub(:template).and_return(@error_code.to_s)
|
108
|
+
begin
|
109
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
110
|
+
response.should render_template("rails_dynamic_errors/errors/#{@error_code}")
|
111
|
+
rescue ActionView::MissingTemplate => exception
|
112
|
+
exception.message.should =~ /Missing template rails_dynamic_errors\/errors\/#{@error_code}/
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when a custom error template is not available" do
|
118
|
+
it "uses the show template" do
|
119
|
+
build_environment_after_exception_for_status_code(@error_code)
|
120
|
+
controller.stub(:template).and_return("show")
|
121
|
+
controller.stub(:template_exists?).and_return(false)
|
122
|
+
get :show, code: @error_code, use_route: :rails_dynamic_errors
|
123
|
+
response.should render_template("rails_dynamic_errors/errors/show")
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,56 @@
|
|
1
|
+
body { background-color: #fff; color: #333; }
|
2
|
+
|
3
|
+
body, p, ol, ul, td {
|
4
|
+
font-family: verdana, arial, helvetica, sans-serif;
|
5
|
+
font-size: 13px;
|
6
|
+
line-height: 18px;
|
7
|
+
}
|
8
|
+
|
9
|
+
pre {
|
10
|
+
background-color: #eee;
|
11
|
+
padding: 10px;
|
12
|
+
font-size: 11px;
|
13
|
+
}
|
14
|
+
|
15
|
+
a { color: #000; }
|
16
|
+
a:visited { color: #666; }
|
17
|
+
a:hover { color: #fff; background-color:#000; }
|
18
|
+
|
19
|
+
div.field, div.actions {
|
20
|
+
margin-bottom: 10px;
|
21
|
+
}
|
22
|
+
|
23
|
+
#notice {
|
24
|
+
color: green;
|
25
|
+
}
|
26
|
+
|
27
|
+
.field_with_errors {
|
28
|
+
padding: 2px;
|
29
|
+
background-color: red;
|
30
|
+
display: table;
|
31
|
+
}
|
32
|
+
|
33
|
+
#error_explanation {
|
34
|
+
width: 450px;
|
35
|
+
border: 2px solid red;
|
36
|
+
padding: 7px;
|
37
|
+
padding-bottom: 0;
|
38
|
+
margin-bottom: 20px;
|
39
|
+
background-color: #f0f0f0;
|
40
|
+
}
|
41
|
+
|
42
|
+
#error_explanation h2 {
|
43
|
+
text-align: left;
|
44
|
+
font-weight: bold;
|
45
|
+
padding: 5px 5px 5px 15px;
|
46
|
+
font-size: 12px;
|
47
|
+
margin: -7px;
|
48
|
+
margin-bottom: 0px;
|
49
|
+
background-color: #c00;
|
50
|
+
color: #fff;
|
51
|
+
}
|
52
|
+
|
53
|
+
#error_explanation ul li {
|
54
|
+
font-size: 12px;
|
55
|
+
list-style: square;
|
56
|
+
}
|