contingency 0.1.3
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +204 -0
- data/Rakefile +1 -0
- data/contingency.gemspec +27 -0
- data/lib/contingency.rb +37 -0
- data/lib/contingency/adapters/interface.rb +48 -0
- data/lib/contingency/configuration.rb +23 -0
- data/lib/contingency/exceptions.rb +21 -0
- data/lib/contingency/plan.rb +43 -0
- data/lib/contingency/version.rb +3 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 21458e2b0634b9e68a901d2008418bbae490fdfe
|
4
|
+
data.tar.gz: c590972c7818e0f7c06dc2227fe72d3b78124f1c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b41aa57923b2beeb99aa025f72cf65b6805f26e071565649c6be14eb5e7c9806f82d570acce03d1fc411e1cbf0fb472f28b31e2c663d719cde0b6cc951018fe5
|
7
|
+
data.tar.gz: c3871c5eeb363b533472ec76c6c6d3eec1cd94b23afd650d0fb62fc00219e9602dc74aae6663e0a6436475ddd75e84278cb38cfd9e11e527e43335c3256a24cb
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Christopher Keele
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
<a name='contingency'>
|
2
|
+
# Contingency
|
3
|
+
</a>
|
4
|
+
|
5
|
+
> "Freedom is the recognition of contingency."
|
6
|
+
|
7
|
+
> * *Richard M. Rorty*
|
8
|
+
|
9
|
+
Contingency is the custom error page controller you've implemented in every project you've ever written. It's compatibile with every framework you've ever implemented a project in. A [Contingency Plan](#supported-integrations) has been written for every Ruby framework you're familiar with. And odds are, its better tested than your implementation.
|
10
|
+
|
11
|
+
So for the love of god, stop implementing it yourself.
|
12
|
+
|
13
|
+
It's quick to get started, gives you full customization over Exception coverage, gives you full control over rendering your own error page, and has a contingency plan itself in the event that your custom error views trigger an Exception.
|
14
|
+
|
15
|
+
It's also very lightweight: the core functionality (the module in `contingency/plan.rb`) is less than 50 lines; and only adds 3 integration methods, 2 helper methods, and 1 controller action method to your controller. Everything but the controller method is private. The rest of the codebase else is just a matter of integration. It's a hard codebase to get lost in.
|
16
|
+
|
17
|
+
Experience true freedom, and make yourself a Contingency Plan.
|
18
|
+
|
19
|
+
<a name='table-of-contents'>
|
20
|
+
## Table of Contents
|
21
|
+
</a>
|
22
|
+
|
23
|
+
* [Installation](#installation)
|
24
|
+
* [Configuration](#configuration)
|
25
|
+
* [Supported Integrations](#supported-integrations)
|
26
|
+
* [Rails](#rails-integration)
|
27
|
+
* [Custom Integrations](#custom-integrations)
|
28
|
+
* [Integrating Contingency Yourself](#integrating-contingency-yourself)
|
29
|
+
* [Integration Dependencies](#three-integration-methods)
|
30
|
+
* [Versioning](#versioning)
|
31
|
+
* [Contingency Versioning](#contingency-versioning)
|
32
|
+
* [Integration Versioning](#contingency-integration-versioning)
|
33
|
+
* [Contributing Integrations](#contributing-integrations)
|
34
|
+
* [Contributing to Contingency](#contributing-to-contingency)
|
35
|
+
* [Credits](#credits)
|
36
|
+
* [Contributers](#contributers)
|
37
|
+
* [Shout-Outs](#shout-outs)
|
38
|
+
|
39
|
+
<a name='installation'>
|
40
|
+
## Installation
|
41
|
+
</a>
|
42
|
+
|
43
|
+
Add these lines to your application's Gemfile:
|
44
|
+
|
45
|
+
gem 'contingency', '~> 1.0'
|
46
|
+
gem 'contingency_my-framework-name', '~> x.0'
|
47
|
+
|
48
|
+
...where [my-framework-name](#supported-integrations) is the name of your framework.
|
49
|
+
|
50
|
+
Then, execute:
|
51
|
+
|
52
|
+
$ bundle
|
53
|
+
|
54
|
+
<a name='configuration'>
|
55
|
+
## Configuration
|
56
|
+
</a>
|
57
|
+
|
58
|
+
Contingency
|
59
|
+
|
60
|
+
<a name='supported-integrations'>
|
61
|
+
## Supported Integrations
|
62
|
+
</a>
|
63
|
+
|
64
|
+
<table>
|
65
|
+
<thead>
|
66
|
+
<tr>
|
67
|
+
<td>Contingency Plan</td>
|
68
|
+
<td>Integration Quality</td>
|
69
|
+
<td>Version</td>
|
70
|
+
<td>Maintainer</td>
|
71
|
+
</tr>
|
72
|
+
</thead>
|
73
|
+
<tbody>
|
74
|
+
<tr>
|
75
|
+
<td>
|
76
|
+
<a href='#rails-integration'>Rails</a>
|
77
|
+
</td>
|
78
|
+
<td>
|
79
|
+
<a href='#poor-dependency-management'>Poor</a>
|
80
|
+
</td>
|
81
|
+
<td>
|
82
|
+
<a href='https://www.github.com/christhekeele/contingency_rails'>0.0.1</a>
|
83
|
+
</td>
|
84
|
+
<td>
|
85
|
+
<a href='https://www.github.com/christhekeele/contingency_rails/issues'>christhekeele</a>
|
86
|
+
</td>
|
87
|
+
</tr>
|
88
|
+
</tbody>
|
89
|
+
</table>
|
90
|
+
|
91
|
+
<a name='rails-integration'>
|
92
|
+
### Rails
|
93
|
+
</a>
|
94
|
+
|
95
|
+
<a name='custom-integrations'>
|
96
|
+
## Custom Integrations
|
97
|
+
</a>
|
98
|
+
|
99
|
+
If the framework you're using doesn't have a Contingency Plan integration, you're only 3 methods away from integrating it yourself.
|
100
|
+
|
101
|
+
<a name='integrating-contingency-yourself'>
|
102
|
+
### Integrating it Yourself
|
103
|
+
</a>
|
104
|
+
|
105
|
+
It's easy to integrate Contingency into your own app. Contingency only relys on 3 methods to communicate with your framework:
|
106
|
+
|
107
|
+
<a name='three-integration-methods'>
|
108
|
+
#### Integration Dependencies
|
109
|
+
</a>
|
110
|
+
|
111
|
+
<a name='for-the-love-of-god-contribute'>
|
112
|
+
</a>
|
113
|
+
|
114
|
+
If you decide to go through this trouble, you really should consider [contributing your Contingency Plan integration](#contributing-integrations) to Contingency.</a> I'll be more than happy to help you develop your integration until [it meets our minimum quality standards](#versioning), if it doesn't out-of-the-box.
|
115
|
+
|
116
|
+
<a name='versioning'>
|
117
|
+
## Versioning
|
118
|
+
</a>
|
119
|
+
|
120
|
+
<a name='contingency-versioning'>
|
121
|
+
### Contingency Versioning
|
122
|
+
</a>
|
123
|
+
|
124
|
+
Contingency itself is versioned as it changes. It bumps its major version as its API changes, which is rarely, as its public API only requires [3 methods](#three-integration-methods). It uses [symantic versioning](http://http://semver.org/). This means you should safely be able to install it with [loose bundler dependencies](#installation).
|
125
|
+
|
126
|
+
<a name='contingency-integration-versioning'>
|
127
|
+
### Integration Versioning
|
128
|
+
</a>
|
129
|
+
|
130
|
+
<a name='great-dependency-management'>
|
131
|
+
#### Great
|
132
|
+
</a>
|
133
|
+
|
134
|
+
Contingency Plans should be versioned [with their frameworks](#supported-integrations). Integrations that follow this simple requirement are labeled as [**great**](#supported-integrations).
|
135
|
+
|
136
|
+
<a name='good-dependency-management'>
|
137
|
+
#### Good
|
138
|
+
</a>
|
139
|
+
|
140
|
+
Contingency Plans that keep up with at least [the major version of their framework](http://http://semver.org/) will result in the integration being labeled as [**good**](#supported-integrations).
|
141
|
+
|
142
|
+
<a name='poor-dependency-management'>
|
143
|
+
#### Poor
|
144
|
+
</a>
|
145
|
+
|
146
|
+
Contingency Plans that fail to keep up with [the major version of their framework](http://http://semver.org/) will result in the integration being labeled as [**poor**](#supported-integrations).
|
147
|
+
|
148
|
+
<a name='bad-dependency-management'>
|
149
|
+
#### Bad
|
150
|
+
</a>
|
151
|
+
|
152
|
+
Contingency Plans that throw off the shackles of [symantic versioning](http://http://semver.org/) and don't follow it from the get-go, Pull Request, or fall very behind will result in the integration being labeled as [**bad**](#supported-integrations).
|
153
|
+
|
154
|
+
I keep up with these frameworks through [the Bundle Scout](https://bundlescout.com). You should, too! **Checkest thineself lest thy wrekest thineself**.
|
155
|
+
|
156
|
+
<a name='contributing-integrations'>
|
157
|
+
## Contributing Integrations
|
158
|
+
</a>
|
159
|
+
|
160
|
+
See [contingency_rails](https://www.github.com/christhekeele/contingency_rails) as an example.
|
161
|
+
|
162
|
+
1. Create a new gem named after your framework (`bundle gem contingency-my_integration`)
|
163
|
+
1. Add Contingency as a dependency to your gemspec and bundle install
|
164
|
+
1. Generate an integration template (`bundle exec rake contingency:generate:plan[my_integration]`)
|
165
|
+
1. Implement the 3 methods that rake instructs you to
|
166
|
+
1. Commit your changes (`git commit -am 'Created my_integration'`)
|
167
|
+
1. Push (`git push origin master`)
|
168
|
+
1. Follow [the steps below](#contributing-to-contingency) to add autoloading your Contingency Plan in Contingency core and wait get your Pull Request accepted
|
169
|
+
1. Create the intital build of your gem (`gem build contingency-my_integration`)
|
170
|
+
1. Release your gem (`gem push contingency-my_integration.gem`)
|
171
|
+
1. Revel in the fact that you've provided a Contingency Plan for you and yours
|
172
|
+
1. Continue to mantain your integration over time by [handling API changes and bumping the version number in accordance with the framework](#versioning), lest your integration be marked as deprecated.
|
173
|
+
|
174
|
+
|
175
|
+
<a name='contributing-to-contingency'>
|
176
|
+
## Contributing to Contingency
|
177
|
+
</a>
|
178
|
+
|
179
|
+
1. Fork it
|
180
|
+
1. Create your feature branch (`git checkout -b my-new-feature`)
|
181
|
+
1. Add the name of your integration to the integrations array in the contingency/integration.rb file if [you're contributing a Contingency Plan](#contributing-integrations)
|
182
|
+
1. Commit your changes (`git commit -am 'Add some feature'`)
|
183
|
+
1. Push to the branch (`git push origin my-new-feature`)
|
184
|
+
1. Create new Pull Request
|
185
|
+
1. I tell you to go back and write some tests if you haven't already
|
186
|
+
1. I tell you to go back and update the README.md if you haven't already
|
187
|
+
1. I accept your Pull Request
|
188
|
+
|
189
|
+
<a name='credits'>
|
190
|
+
## Credits
|
191
|
+
</a>
|
192
|
+
|
193
|
+
<a name='contributers'>
|
194
|
+
### Contributers
|
195
|
+
</a>
|
196
|
+
|
197
|
+
* None, aside from [the creator](https://www.github.com/christhekeele/contingency). [Be the first!](#contributing-to-contingency)!
|
198
|
+
|
199
|
+
<a name='shout-outs'>
|
200
|
+
### Shout-Outs
|
201
|
+
</a>
|
202
|
+
|
203
|
+
* Thanks to [nathanl](https://github.com/nathanl) and his excellent authorization gem, [Authority](https://github.com/nathanl/authority), the structure of which inspired this one.
|
204
|
+
* Thanks to [ryanb](https://github.com/ryanb), and his subscription-worthy [Railscasts](http://railscasts.com/), which have inspired us all. Especially us [Pro users](http://railscasts.com/pro).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/contingency.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'contingency/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "contingency"
|
8
|
+
spec.version = Contingency::VERSION
|
9
|
+
spec.authors = ["Christopher Keele"]
|
10
|
+
spec.email = ["dev@chriskeele.com"]
|
11
|
+
spec.description = "A framework agnostic exception catcher and custom error page generator."
|
12
|
+
spec.summary = "Handle your ruby web application's errors your way, with your own beautiful customized error pages. Framework agnostic with several integrations and i18n support."
|
13
|
+
# spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "activesupport", ">= 3.0.0"
|
22
|
+
spec.add_dependency "i18n", ">= 0.6.0"
|
23
|
+
spec.add_dependency "rake", ">= 0.8.1.10"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
26
|
+
spec.add_development_dependency "rspec", "~> 2.13"
|
27
|
+
end
|
data/lib/contingency.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/rescuable'
|
3
|
+
require 'logger'
|
4
|
+
require "contingency/exceptions"
|
5
|
+
require "contingency/adapters/interface"
|
6
|
+
|
7
|
+
module Contingency
|
8
|
+
|
9
|
+
class << self
|
10
|
+
alias :configure :initialize
|
11
|
+
attr_accessor :configuration
|
12
|
+
attr_accessor :adapter, :adapters
|
13
|
+
end
|
14
|
+
|
15
|
+
self.adapters = []
|
16
|
+
|
17
|
+
def self.configure
|
18
|
+
self.adapter ||= self.adapters.first || Adapters::Interface
|
19
|
+
self.configuration ||= Configuration.new
|
20
|
+
|
21
|
+
yield(self.adapter.default_configuration) if self.adapter.respond_to?(:default_configuration)
|
22
|
+
yield(configuration) if block_given?
|
23
|
+
|
24
|
+
require "contingency/plan"
|
25
|
+
|
26
|
+
configuration
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.logger
|
30
|
+
@logger ||= configuration.logger
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
require "contingency/configuration"
|
37
|
+
require "contingency/version"
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Contingency
|
2
|
+
|
3
|
+
module Adapters
|
4
|
+
module Interface
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
class InterfaceNotImplementedError < NotImplementedError; end
|
10
|
+
end
|
11
|
+
|
12
|
+
###
|
13
|
+
# Required integration methods go here.
|
14
|
+
# They're implemented here as no-ops that raise an error so
|
15
|
+
# all subclasses have to define them.
|
16
|
+
#
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def catch_errors?
|
20
|
+
raise InterfaceNotImplementedError, "Override this `catch_errors?` method" \
|
21
|
+
" with one that decides if your framework should activate" \
|
22
|
+
" Contingency or not (ie `ENV[RACK_ENV] !== 'development'`)."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module InstanceMethods
|
27
|
+
def error_renderer(code)
|
28
|
+
raise InterfaceNotImplementedError, "Override this `error_renderer` method" \
|
29
|
+
" with one that expects an error code, and uses your framework's" \
|
30
|
+
" render method to find your views for it." \
|
31
|
+
" (ie `render Contingency.configuration.error_template, status: code`," \
|
32
|
+
" or even just `render code`)"
|
33
|
+
end
|
34
|
+
|
35
|
+
def failure_renderer(code)
|
36
|
+
raise InterfaceNotImplementedError, "Override this `failure_renderer` method" \
|
37
|
+
" with one that expects an error code, and uses your framework's" \
|
38
|
+
" render method to display a simple text error page in the event" \
|
39
|
+
" your `#{self.class.name}#error_renderer?`'s render can't render" \
|
40
|
+
" your error template." \
|
41
|
+
" (ie `render status: code, text: Contingency.configuration.error_template`)"
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Contingency
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
attr_accessor :errors, :error_messages,
|
5
|
+
:error_layout, :error_template,
|
6
|
+
:unknown_error_message, :failure_message,
|
7
|
+
:logger
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@errors = {}
|
11
|
+
@error_messages = {}
|
12
|
+
|
13
|
+
@error_layout = ''
|
14
|
+
@error_template = ''
|
15
|
+
|
16
|
+
@unknown_error_message = ['Server Error', 'It looks like something went wrong.']
|
17
|
+
@failure_message = "Server Error: It looks like something went wrong."
|
18
|
+
|
19
|
+
@logger = Logger.new(STDERR)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Contingency
|
2
|
+
module Exceptions
|
3
|
+
class ContingencyError < Exception
|
4
|
+
attr_accessor :message, :backtrace
|
5
|
+
end
|
6
|
+
class RenderedErrorPageException < ContingencyError
|
7
|
+
def initialize
|
8
|
+
@message = 'An error page was explicitly requested.'
|
9
|
+
@backtrace = ['None. No real error occured.']
|
10
|
+
end
|
11
|
+
end
|
12
|
+
class ContingencyPlanException < ContingencyError
|
13
|
+
def initialize(original_exception, handler_exception)
|
14
|
+
@message = "`Contingency::Plan` encountered exception `#{handler_exception.class.name}`" \
|
15
|
+
" while trying to handle exception `#{original_exception.class.name}`:" \
|
16
|
+
"\n#{handler_exception.message}"
|
17
|
+
@backtrace = handler_exception.backtrace
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Contingency
|
2
|
+
|
3
|
+
module Plan
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
extend ActiveSupport::Rescuable
|
6
|
+
|
7
|
+
|
8
|
+
included do
|
9
|
+
extend Contingency.adapter
|
10
|
+
|
11
|
+
if catch_errors?
|
12
|
+
Contingency.configuration.errors.each do |code, exceptions|
|
13
|
+
rescue_from *exceptions, with: ->(exception){ render_error code, exception }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def error
|
19
|
+
render_error(params[:code], Contingency::Exceptions::RenderedErrorPageException.new)
|
20
|
+
end
|
21
|
+
|
22
|
+
def error_report(exception)
|
23
|
+
"#{exception.class} raised on #{request.fullpath}:" \
|
24
|
+
"\n#{exception.message}" \
|
25
|
+
"\nBacktrace:" \
|
26
|
+
"\n#{exception.backtrace.join("\n")}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def render_error(code, exception)
|
30
|
+
message, description = Contingency.configuration.error_messages.fetch(code, Contingency.configuration.unknown_error_message)
|
31
|
+
error_logger = logger.method(code.to_i < 500 ? :info : :error)
|
32
|
+
error_logger.call "#{code}: #{description}.\n" + error_report(exception)
|
33
|
+
@code = code
|
34
|
+
@message = message
|
35
|
+
@description = description
|
36
|
+
error_renderer(code)
|
37
|
+
rescue Exception => handler_exception
|
38
|
+
logger.fatal error_report(Contingency::Exceptions::ContingencyPlanException.new(exception, handler_exception))
|
39
|
+
failure_renderer(500)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: contingency
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christopher Keele
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-04-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: i18n
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.6.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.6.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.8.1.10
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.8.1.10
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.13'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.13'
|
83
|
+
description: A framework agnostic exception catcher and custom error page generator.
|
84
|
+
email:
|
85
|
+
- dev@chriskeele.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- contingency.gemspec
|
96
|
+
- lib/contingency.rb
|
97
|
+
- lib/contingency/adapters/interface.rb
|
98
|
+
- lib/contingency/configuration.rb
|
99
|
+
- lib/contingency/exceptions.rb
|
100
|
+
- lib/contingency/plan.rb
|
101
|
+
- lib/contingency/version.rb
|
102
|
+
homepage:
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata: {}
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 2.0.0
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: Handle your ruby web application's errors your way, with your own beautiful
|
126
|
+
customized error pages. Framework agnostic with several integrations and i18n support.
|
127
|
+
test_files: []
|
128
|
+
has_rdoc:
|