rambulance 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +21 -0
  5. data/Appraisals +28 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +114 -0
  9. data/Rakefile +25 -0
  10. data/gemfiles/rails_32.gemfile +9 -0
  11. data/gemfiles/rails_40.gemfile +9 -0
  12. data/gemfiles/rails_41.gemfile +9 -0
  13. data/gemfiles/rails_edge.gemfile +14 -0
  14. data/lib/generators/rambulance/exceptions_app_generator.rb +20 -0
  15. data/lib/generators/rambulance/install_generator.rb +47 -0
  16. data/lib/generators/rambulance/templates/exceptions_app.rb +13 -0
  17. data/lib/generators/rambulance/templates/rambulance.rb +43 -0
  18. data/lib/generators/rambulance/templates/views/bad_request.html.erb +58 -0
  19. data/lib/generators/rambulance/templates/views/bad_request.html.haml +54 -0
  20. data/lib/generators/rambulance/templates/views/bad_request.json.jbuilder +1 -0
  21. data/lib/generators/rambulance/templates/views/forbidden.html.erb +58 -0
  22. data/lib/generators/rambulance/templates/views/forbidden.html.haml +54 -0
  23. data/lib/generators/rambulance/templates/views/forbidden.json.jbuilder +1 -0
  24. data/lib/generators/rambulance/templates/views/internal_server_error.html.erb +58 -0
  25. data/lib/generators/rambulance/templates/views/internal_server_error.html.haml +54 -0
  26. data/lib/generators/rambulance/templates/views/internal_server_error.json.jbuilder +1 -0
  27. data/lib/generators/rambulance/templates/views/not_found.html.erb +59 -0
  28. data/lib/generators/rambulance/templates/views/not_found.html.haml +55 -0
  29. data/lib/generators/rambulance/templates/views/not_found.json.jbuilder +1 -0
  30. data/lib/generators/rambulance/templates/views/unprocessable_entity.html.erb +59 -0
  31. data/lib/generators/rambulance/templates/views/unprocessable_entity.html.haml +55 -0
  32. data/lib/generators/rambulance/templates/views/unprocessable_entity.json.jbuilder +1 -0
  33. data/lib/rambulance.rb +26 -0
  34. data/lib/rambulance/exceptions_app.rb +56 -0
  35. data/lib/rambulance/railtie.rb +26 -0
  36. data/lib/rambulance/version.rb +3 -0
  37. data/rambulance.gemspec +33 -0
  38. data/spec/fake_app/app/views/errors/internal_server_error.html.erb +1 -0
  39. data/spec/fake_app/app/views/errors/internal_server_error.json.jbuilder +1 -0
  40. data/spec/fake_app/app/views/errors/not_found.html.erb +1 -0
  41. data/spec/fake_app/app/views/errors/not_found.json.jbuilder +1 -0
  42. data/spec/fake_app/app/views/layouts/error.html.erb +10 -0
  43. data/spec/fake_app/lib/exceptions_app.rb +12 -0
  44. data/spec/fake_app/rails_app.rb +59 -0
  45. data/spec/requests/error_json_spec.rb +40 -0
  46. data/spec/requests/error_page_spec.rb +53 -0
  47. data/spec/spec_helper.rb +19 -0
  48. metadata +255 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 371368ef15c8a2428abac262161e5d591a3b1e21
4
+ data.tar.gz: a4b52cc04381d65a5b787a88241d0c8268376955
5
+ SHA512:
6
+ metadata.gz: 85182daad34f54b4c63ecc95984dc4b94047bb47b058dd9c596d23593ec399c60b152b242b43eeb8050af2fdfc5feecf272702abade061e2857a717b20df4bc8
7
+ data.tar.gz: ec70b4eb6b526bc4e9ba6532a90f39fa9c9e67ca072ab50e358896166558c44966be276a51de1db345acd8657065e78da2ba936c154f04a75dbe4d5f846d2eec
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ gemfiles/*.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ *.bundle
20
+ *.so
21
+ *.o
22
+ *.a
23
+ mkmf.log
24
+ *.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format=d
@@ -0,0 +1,21 @@
1
+ script: "bundle install && bundle exec rake spec:all"
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1
7
+ - ruby-head
8
+ - jruby
9
+ - rbx-2
10
+
11
+ gemfile:
12
+ - gemfiles/rails_32.gemfile
13
+ - gemfiles/rails_40.gemfile
14
+ - gemfiles/rails_41.gemfile
15
+ - gemfiles/rails_edge.gemfile
16
+
17
+ matrix:
18
+ allow_failures:
19
+ - rvm: ruby-head
20
+ - gemfile: gemfiles/rails_edge.gemfile
21
+ fast_finish: true
@@ -0,0 +1,28 @@
1
+ appraise "rails_32" do
2
+ gem "activesupport", "~> 3.2.0"
3
+ gem "actionpack", "~> 3.2.0"
4
+ gem "railties", "~> 3.2.0"
5
+ end
6
+
7
+ appraise "rails_40" do
8
+ gem "activesupport", "~> 4.0.0"
9
+ gem "actionpack", "~> 4.0.0"
10
+ gem "railties", "~> 4.0.0"
11
+ end
12
+
13
+ appraise "rails_41" do
14
+ gem "activesupport", "~> 4.1.0"
15
+ gem "actionpack", "~> 4.1.0"
16
+ gem "railties", "~> 4.1.0"
17
+ end
18
+
19
+ appraise "rails_edge" do
20
+ git 'git://github.com/rails/rails.git' do
21
+ gem "activesupport", require: 'active_support'
22
+ gem "actionpack", require: 'action_pack'
23
+ gem "railties"
24
+ end
25
+
26
+ gem 'minitest', '~> 5.3.4'
27
+ gem 'rspec-rails', '2.99.0.beta1'
28
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rambulance.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Yuki Nishijima
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,114 @@
1
+ # Rambulance [![Build Status](https://travis-ci.org/yuki24/rambulance.svg?branch=master)](https://travis-ci.org/yuki24/rambulance)
2
+
3
+ Rambulance provides a simple and safe way to dynamically render error pages for Rails apps.
4
+
5
+ ## Features
6
+
7
+ ### Simple and Safe
8
+
9
+ Rambulance's exceptions app is simple, skinny and well-tested. It inherits `ActionController::Base`, so it works fine even if your `ApplicationController` has an issue.
10
+
11
+ ### Flexible
12
+
13
+ You have full control of what error page to display for a specific exception. It can also render json responses. It even provides a way to create a custom exceptions app.
14
+
15
+ ### Easy installation and development
16
+
17
+ You don't have to configure things that every single person has to do and Rambulance does everything for you.
18
+
19
+ ## Installation and Usage
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ ```
24
+ gem 'rambulance'
25
+ ```
26
+
27
+ And then execute:
28
+
29
+ ```
30
+ $ rails g rambulance:install
31
+ ```
32
+
33
+ Now you can start editing templates like `app/views/errors/not_found.html.erb`. Edit, run `rails server` and open [`localhost:3000/rambulance/not_found`](http://localhost:3000/rambulance/404)!
34
+
35
+ ## Setting Pairs of Exceptions and HTTP Statuses
36
+
37
+ Open `config/initializers/rambulance.rb` and to configure the list of pairs of exception/corresponding http status.
38
+ For example, if you want to display:
39
+
40
+ * 422(unprocessable entity) for `ActiveRecord::RecordNotUnique`
41
+ * 403(forbidden) for `CanCan::AccessDenied`
42
+ * 404(not found) for `YourCustomException`
43
+
44
+ Then do the following:
45
+
46
+ ```ruby
47
+ # config/initializers/rambulance.rb
48
+ config.rescue_responses = {
49
+ "ActiveRecord::RecordNotUnique" => :unprocessable_entity,
50
+ "CanCan::AccessDenied" => :forbidden,
51
+ "YourCustomException" => :not_found
52
+ }
53
+ ```
54
+
55
+ ## Local Development
56
+
57
+ There are 2 ways of editing the templates.
58
+
59
+ <!---
60
+ ### Open [`localhost:3000/rambulance`](http://localhost:3000/rambulance) in Your Browser
61
+
62
+ This page tells all the error pages as well as all the pairs of exceptions/corresponding http status. This is useful when you want to edit templates without changing Rails configuration. Click on one of the links in the page to see what the error page looks like.
63
+
64
+ **This feature hasn't been implemented yet.**
65
+ -->
66
+
67
+ ### Open `localhost:3000/rambulance/***` in Your Browser
68
+
69
+ Just go to one of the error pages via Rambulance:
70
+ * [`localhost:3000/rambulance/not_found`](http://localhost:3000/rambulance/404) or
71
+ * [`localhost:3000/rambulance/internal_server_error`](http://localhost:3000/rambulance/500)
72
+
73
+ This is useful when you want to edit templates without changing Rails configuration.
74
+
75
+ ### Set `consider_all_requests_local` to _false_
76
+
77
+ Change `config.consider_all_requests_local` to _false_ in `config/environments/development.rb`.
78
+
79
+ ```
80
+ config.consider_all_requests_local = false
81
+ ```
82
+
83
+ This simulates how your production app displays error pages so you can actually raise an exception in your app and see how it works. Don't forget to change `consider_all_requests_local` back to _true_ after you tried this strategy.
84
+
85
+ ## Custom Exceptions App
86
+
87
+ If you want to do some more things in a exceptions app, you can also write your own custom exceptions app:
88
+
89
+ ```
90
+ $ rails g rambulance:exceptions_app
91
+ ```
92
+
93
+ It'll generate your own custom exceptions app. You can use whatever techniques you use in controllers like `before_filter` and `flash[:notice] = "message..."` since it's a grandchild of `ActionController::Base`!
94
+
95
+ **Keep in mind that you shouldn't do too many things because something already went wrong with your application!**
96
+
97
+ ## Supported Versions
98
+
99
+ * Ruby 1.9.3, 2.0.0, 2.1.2, JRuby 1.7.11, Rubinius 2.2.6
100
+ * Rails 3.2, 4.0, 4.1
101
+
102
+ Rambulance doesn't work with Rails 3.1 and below since they don't provide any way to use a custom exceptions app.
103
+
104
+ ## Contributing
105
+
106
+ 1. Fork it ( https://github.com/yuki24/rambulance/fork )
107
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
108
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
109
+ 4. Push to the branch (`git push origin my-new-feature`)
110
+ 5. Create a new Pull Request
111
+
112
+ ## License
113
+
114
+ Copyright (c) 2014 Yuki Nishijima. See LICENSE.txt for further details.
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ task default: "spec:all"
11
+
12
+ namespace :spec do
13
+ desc "Run Tests with the default exceptions app"
14
+ task :default do
15
+ sh "bundle exec rake -t spec"
16
+ end
17
+
18
+ desc "Run Tests with a custom exceptions app"
19
+ task :custom do
20
+ sh "bundle exec rake -t spec CUSTOM_EXCEPTIONS_APP=1"
21
+ end
22
+
23
+ desc "Run tests with both of the default and custom apps"
24
+ task(:all).enhance(%w(default custom))
25
+ end
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 3.2.0"
6
+ gem "actionpack", "~> 3.2.0"
7
+ gem "railties", "~> 3.2.0"
8
+
9
+ gemspec :path => "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.0.0"
6
+ gem "actionpack", "~> 4.0.0"
7
+ gem "railties", "~> 4.0.0"
8
+
9
+ gemspec :path => "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.1.0"
6
+ gem "actionpack", "~> 4.1.0"
7
+ gem "railties", "~> 4.1.0"
8
+
9
+ gemspec :path => "../"
@@ -0,0 +1,14 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git "git://github.com/rails/rails.git" do
6
+ gem "activesupport", :require => "active_support"
7
+ gem "actionpack", :require => "action_pack"
8
+ gem "railties"
9
+ end
10
+
11
+ gem "minitest", "~> 5.3.4"
12
+ gem "rspec-rails", "2.99.0.beta1"
13
+
14
+ gemspec :path => "../"
@@ -0,0 +1,20 @@
1
+ module Rambulance
2
+ module Generators
3
+ class ExceptionsAppGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ def self.banner #:nodoc:
7
+ <<-BANNER.chomp
8
+ rails g rambulance:exceptions_app
9
+
10
+ Creates a custom exceptions app.
11
+ BANNER
12
+ end
13
+
14
+ desc ''
15
+ def copy_exceptions_app #:nodoc:
16
+ copy_file "exceptions_app.rb", "app/handlers/exceptions_app.rb"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,47 @@
1
+ module Rambulance
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ class_option :template_engine, type: :string, aliases: '-e', desc: 'Template engine for the views. Available options are "erb" and "haml".'
7
+
8
+ def self.banner #:nodoc:
9
+ <<-BANNER.chomp
10
+ rails g rambulance:install
11
+
12
+ Copies all error partial templates and an initializer to your application.
13
+ BANNER
14
+ end
15
+
16
+ desc ''
17
+ def copy_templates #:nodoc:
18
+ say "generating templates:"
19
+ filename_pattern = File.join(self.class.source_root, "views", "*.html.#{template_engine}")
20
+ Dir.glob(filename_pattern).map {|f| File.basename f }.each do |f|
21
+ copy_file "views/#{f}", "app/views/errors/#{f}"
22
+ end
23
+
24
+ filename_pattern = File.join(self.class.source_root, "views", "*.json.jbuilder")
25
+ Dir.glob(filename_pattern).map {|f| File.basename f }.each do |f|
26
+ copy_file "views/#{f}", "app/views/errors/#{f}"
27
+ end
28
+ end
29
+
30
+ def copy_layout #:nodoc:
31
+ say "\ncopying app/views/layouts/application.html.#{template_engine} to app/views/layouts/error.html.#{template_engine}:"
32
+ copy_file Rails.root.join("app/views/layouts/application.html.#{template_engine}"), "app/views/layouts/error.html.#{template_engine}"
33
+ end
34
+
35
+ def copy_initializer #:nodoc:
36
+ say "\ngenerating initializer:"
37
+ copy_file "rambulance.rb", "config/initializers/rambulance.rb"
38
+ end
39
+
40
+ private
41
+
42
+ def template_engine
43
+ options[:template_engine].try(:to_s).try(:downcase) || 'erb'
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ class ExceptionsApp < Rambulance::ExceptionsApp
2
+ def bad_request
3
+ end
4
+
5
+ def forbidden
6
+ end
7
+
8
+ def not_found
9
+ end
10
+
11
+ def internal_server_error
12
+ end
13
+ end
@@ -0,0 +1,43 @@
1
+ Rambulance.setup do |config|
2
+
3
+ # List of pairs of exception/corresponding http status. In Rails, the default
4
+ # mappings are below:
5
+ #
6
+ # "ActionController::RoutingError" => :not_found,
7
+ # "AbstractController::ActionNotFound" => :not_found,
8
+ # "ActionController::MethodNotAllowed" => :method_not_allowed,
9
+ # "ActionController::UnknownHttpMethod" => :method_not_allowed,
10
+ # "ActionController::NotImplemented" => :not_implemented,
11
+ # "ActionController::UnknownFormat" => :not_acceptable,
12
+ # "ActionController::InvalidAuthenticityToken" => :unprocessable_entity,
13
+ # "ActionDispatch::ParamsParser::ParseError" => :bad_request,
14
+ # "ActionController::BadRequest" => :bad_request,
15
+ # "ActionController::ParameterMissing" => :bad_request,
16
+ # "ActiveRecord::RecordNotFound" => :not_found,
17
+ # "ActiveRecord::StaleObjectError" => :conflict,
18
+ # "ActiveRecord::RecordInvalid" => :unprocessable_entity,
19
+ # "ActiveRecord::RecordNotSaved" => :unprocessable_entity
20
+ #
21
+ # If you add exceptions in this config, Rambulance uses the pairs you defined
22
+ # here *in addition* to the default maddings. You can also override the default
23
+ # mappings although you don't have to in most cases.
24
+ # If Rambulance receives an exception that is not listed here, it'll render
25
+ # the internal server error template and return 500 as http status.
26
+ config.rescue_responses = {
27
+ # "ActiveRecord::RecordNotUnique" => :unprocessable_entity,
28
+ # "CanCan::AccessDenied" => :forbidden,
29
+ # "Pundit::NotAuthorizedError" => :forbidden,
30
+ # "YourCustomException" => :not_found
31
+ }
32
+
33
+ # The template name for the layout of the error pages. The default value is
34
+ # 'error'. For exmaple, if this value is set to "error_page", Rambulance uses
35
+ # 'app/views/layout/error_page.html.erb' as a layout for all the error pages.
36
+ config.layout_name = "error"
37
+
38
+ # The directry name to organize error page templates. The default value is
39
+ # 'errors'. For exmaple, if this value is set to "error_pages", Rambulance
40
+ # uses e.g. 'app/views/error_pages/not_found.html.erb'.
41
+ config.view_path = "errors"
42
+
43
+ end
@@ -0,0 +1,58 @@
1
+ <style>
2
+ div.dialog {
3
+ color: #2E2F30;
4
+ text-align: center;
5
+ font-family: arial, sans-serif;
6
+ margin: 0;
7
+ width: 95%;
8
+ max-width: 33em;
9
+ margin: 4em auto;
10
+ }
11
+
12
+ div.dialog > div {
13
+ border: 1px solid #CCC;
14
+ border-right-color: #999;
15
+ border-left-color: #999;
16
+ border-bottom-color: #BBB;
17
+ border-top: #B00100 solid 4px;
18
+ border-top-left-radius: 9px;
19
+ border-top-right-radius: 9px;
20
+ background-color: white;
21
+ padding: 7px 12% 0;
22
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
23
+ }
24
+
25
+ h1 {
26
+ font-size: 100%;
27
+ color: #730E15;
28
+ line-height: 1.5em;
29
+ margin: 10px 0;
30
+ }
31
+
32
+ div.dialog p {
33
+ margin: 16px 0;
34
+ }
35
+
36
+ div.dialog > p {
37
+ margin: 0 0 1em;
38
+ padding: 1em;
39
+ background-color: #F7F7F7;
40
+ border: 1px solid #CCC;
41
+ border-right-color: #999;
42
+ border-left-color: #999;
43
+ border-bottom-color: #999;
44
+ border-bottom-left-radius: 4px;
45
+ border-bottom-right-radius: 4px;
46
+ border-top-color: #DADADA;
47
+ color: #666;
48
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
49
+ }
50
+ </style>
51
+
52
+ <!-- This file lives in app/views/errors/bad_request.html.erb -->
53
+ <div class="dialog">
54
+ <div>
55
+ <h1>Bad request</h1>
56
+ </div>
57
+ <p>The service received a incomplete request.</p>
58
+ </div>