exception_manager 1.0.0
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 +16 -0
- data/.rspec +2 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +121 -0
- data/Rakefile +5 -0
- data/exception_manager.gemspec +25 -0
- data/lib/exception_manager/config.rb +50 -0
- data/lib/exception_manager/methods/locals.rb +10 -0
- data/lib/exception_manager/methods/subject.rb +5 -0
- data/lib/exception_manager/methods/subject_class_variables.rb +11 -0
- data/lib/exception_manager/methods/subject_instance_variables.rb +10 -0
- data/lib/exception_manager/patch.rb +30 -0
- data/lib/exception_manager/version.rb +8 -0
- data/lib/exception_manager.rb +15 -0
- data/spec/exception_manager/config_spec.rb +56 -0
- data/spec/exception_manager/methods/locals_spec.rb +12 -0
- data/spec/exception_manager/methods/subject_class_variables_spec.rb +23 -0
- data/spec/exception_manager/methods/subject_instance_variables_spec.rb +22 -0
- data/spec/exception_manager/methods/subject_spec.rb +22 -0
- data/spec/exception_manager/patch_spec.rb +81 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/support/exception_examples/letter.rb +22 -0
- data/spec/support/helpers/reset_config_helper.rb +15 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eb305107f1c6f84dd05546de27dbfe8981d0abf7
|
4
|
+
data.tar.gz: 532f25870f02b30b67307f43edcff07951ae9b08
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e397bf900e4f40e762ecc2d37465b3415bc51ae15d6d22423285529ab0b832599bc4357a295d7d495f6ebef22c4278b99b56b95c0d699d9e8a4828ef6adf2794
|
7
|
+
data.tar.gz: ccf737eb0b0bf15288bd19ec90bbecd15eaf7e9fe3fa8685577df191e87a4545d75b48f0aea46da49768ace6dae303c27fe52c016fe66bdca99713937ca9fced
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Ilya Bylich
|
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,121 @@
|
|
1
|
+
# ExceptionManager
|
2
|
+
|
3
|
+
Gem for better exception recording.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'exception_manager'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install exception_manager
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
First of all, make sure that ExceptionManager is enabled in your application.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# config/initializers/exception_manager.rb
|
27
|
+
ExceptionManager.enable!
|
28
|
+
```
|
29
|
+
|
30
|
+
That's it! Now you can use it.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
class TestClassThatRaisesException
|
34
|
+
@@class_variable = :class_value
|
35
|
+
|
36
|
+
def test_error(*args)
|
37
|
+
@instance_variable = :instance_value
|
38
|
+
|
39
|
+
raise 'Test error'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
begin
|
44
|
+
TestClassThatRaisesException.new.test_error(1, 2, 3)
|
45
|
+
rescue => e
|
46
|
+
puts "Subject: #{e.subject}"
|
47
|
+
puts "Locals: #{e.locals}"
|
48
|
+
puts "Instance variables: #{e.subject_instance_variables}"
|
49
|
+
puts "Class variables: #{e.subject_class_variables}"
|
50
|
+
puts "Summary: #{e.summary.inspect}"
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
And if you have `pry`, you can combine it:
|
55
|
+
```ruby
|
56
|
+
e._binding.pry
|
57
|
+
```
|
58
|
+
|
59
|
+
## Integration with monitoring systems like NewRelic
|
60
|
+
|
61
|
+
NewRelic uses `to_s` method for fetching message from exception:
|
62
|
+
[source](https://github.com/newrelic/rpm/blob/master/lib/new_relic/noticed_error.rb#L33).
|
63
|
+
|
64
|
+
Unfortunately you cannot override `to_s` method like this:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
# DO NOT ADD THIS CODE TO YOUR PROJECT
|
68
|
+
# IF YOU DON'T WANT TO GET SEGFAULT
|
69
|
+
class YourApiBaseException < StandardError
|
70
|
+
def to_s
|
71
|
+
[super, summary.inspect].join(' ')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
The solution is in this line:
|
77
|
+
[source](https://github.com/newrelic/rpm/blob/master/lib/new_relic/noticed_error.rb#L31)
|
78
|
+
|
79
|
+
Instead of overriding `to_s` method we can override `original_exception` method:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# This code is safe
|
83
|
+
class YourApiBaseException < StandardError
|
84
|
+
def original_exception
|
85
|
+
message_for_new_relic = [message, summary.inspect].join(' ')
|
86
|
+
self.exception(message_for_new_relic)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
From this moment all exceptions inherited from `YourApiBaseException` will have message
|
92
|
+
with exception summary:
|
93
|
+
```ruby
|
94
|
+
begin
|
95
|
+
raise YourApiBaseException, 'my custom message'
|
96
|
+
rescue YourApiBaseException => e
|
97
|
+
puts e.original_exception.to_s # this is exactly what NewRelic gem calls
|
98
|
+
end
|
99
|
+
# => 'my custom message {:locals=>..., :subject=>..., }'
|
100
|
+
```
|
101
|
+
|
102
|
+
|
103
|
+
Other systems may use `message` method, so the code will look like:
|
104
|
+
```ruby
|
105
|
+
class YourApiBaseException < StandardError
|
106
|
+
def message
|
107
|
+
[super, summary.inspect].join(' ')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
If you don't know exactly which method is used in your monitoring system,
|
113
|
+
you can simply override both :smile:
|
114
|
+
|
115
|
+
## Contributing
|
116
|
+
|
117
|
+
1. Fork it ( https://github.com/[my-github-username]/exception_manager/fork )
|
118
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
119
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
120
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
121
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'exception_manager/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'exception_manager'
|
8
|
+
spec.version = ExceptionManager::Version::STRING
|
9
|
+
spec.authors = ['Ilya Bylich']
|
10
|
+
spec.email = ['ibylich@gmail.com']
|
11
|
+
spec.summary = 'Tool for managing exceptions'
|
12
|
+
spec.description = %q{Gem for inspecting local and class/instance variables when raising exceptions}
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
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_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'rspec', '~> 3.2.0'
|
24
|
+
spec.add_development_dependency 'rspec-its', '~> 1.2.0'
|
25
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module ExceptionManager::Config
|
4
|
+
def enable!
|
5
|
+
tracepoint.enable
|
6
|
+
end
|
7
|
+
|
8
|
+
def disable!
|
9
|
+
tracepoint.disable
|
10
|
+
end
|
11
|
+
|
12
|
+
def enabled?
|
13
|
+
tracepoint.enabled?
|
14
|
+
end
|
15
|
+
|
16
|
+
def disabled?
|
17
|
+
!enabled?
|
18
|
+
end
|
19
|
+
|
20
|
+
def tracepoint
|
21
|
+
@tracepoint ||= TracePoint.new(:raise) do |tp|
|
22
|
+
if ExceptionManager.applicable?(tp.raised_exception)
|
23
|
+
tp.raised_exception._binding = tp.binding
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def filters
|
29
|
+
@filters ||= []
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_filter(&block)
|
33
|
+
filters << block
|
34
|
+
end
|
35
|
+
|
36
|
+
def reset_filters!
|
37
|
+
@filters = []
|
38
|
+
end
|
39
|
+
|
40
|
+
def applicable?(exception)
|
41
|
+
filters.all? do |filter|
|
42
|
+
filter.call(exception)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def logger
|
47
|
+
@logger = Logger.new(STDOUT)
|
48
|
+
end
|
49
|
+
attr_writer :logger
|
50
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class ExceptionManager::Methods::SubjectClassVariables
|
2
|
+
def self.run(exception_binding)
|
3
|
+
exception_binding.eval %q{
|
4
|
+
klass = is_a?(Class) ? self : self.class
|
5
|
+
klass.class_variables.inject({}) do |hash, class_variable_name|
|
6
|
+
hash[class_variable_name] = klass.class_variable_get(class_variable_name)
|
7
|
+
hash
|
8
|
+
end
|
9
|
+
}
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class ExceptionManager::Methods::SubjectInstanceVariables
|
2
|
+
def self.run(exception_binding)
|
3
|
+
exception_binding.eval %q{
|
4
|
+
instance_variables.inject({}) do |hash, instance_variable_name|
|
5
|
+
hash[instance_variable_name] = instance_variable_get(instance_variable_name)
|
6
|
+
hash
|
7
|
+
end
|
8
|
+
}
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ExceptionManager::ExceptionPatch
|
2
|
+
attr_accessor :_binding
|
3
|
+
|
4
|
+
def locals
|
5
|
+
ExceptionManager::Methods::Locals.run(_binding)
|
6
|
+
end
|
7
|
+
|
8
|
+
def subject
|
9
|
+
ExceptionManager::Methods::Subject.run(_binding)
|
10
|
+
end
|
11
|
+
|
12
|
+
def subject_instance_variables
|
13
|
+
ExceptionManager::Methods::SubjectInstanceVariables.run(_binding)
|
14
|
+
end
|
15
|
+
|
16
|
+
def subject_class_variables
|
17
|
+
ExceptionManager::Methods::SubjectClassVariables.run(_binding)
|
18
|
+
end
|
19
|
+
|
20
|
+
def summary
|
21
|
+
{
|
22
|
+
locals: locals,
|
23
|
+
subject: subject,
|
24
|
+
subject_instance_variables: subject_instance_variables,
|
25
|
+
subject_class_variables: subject_class_variables
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Exception.send(:include, ExceptionManager::ExceptionPatch)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'exception_manager/version'
|
2
|
+
|
3
|
+
module ExceptionManager
|
4
|
+
require 'exception_manager/config'
|
5
|
+
extend ExceptionManager::Config
|
6
|
+
|
7
|
+
module Methods
|
8
|
+
autoload :Locals, 'exception_manager/methods/locals'
|
9
|
+
autoload :Subject, 'exception_manager/methods/subject'
|
10
|
+
autoload :SubjectInstanceVariables, 'exception_manager/methods/subject_instance_variables'
|
11
|
+
autoload :SubjectClassVariables, 'exception_manager/methods/subject_class_variables'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'exception_manager/patch'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ExceptionManager::Config, reset_config: true do
|
4
|
+
subject(:manager) { ExceptionManager }
|
5
|
+
|
6
|
+
let(:exception) do
|
7
|
+
begin
|
8
|
+
Letter.new('message', 'from@example.com').deliver_to('to@example.com')
|
9
|
+
rescue => e
|
10
|
+
e
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.enable!/.disable!' do
|
15
|
+
context 'when exception manager is enabled' do
|
16
|
+
before { manager.enable! }
|
17
|
+
it { is_expected.to be_enabled }
|
18
|
+
|
19
|
+
it 'can be disabled' do
|
20
|
+
manager.disable!
|
21
|
+
expect(manager).to be_disabled
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'adds local bindings to exceptions' do
|
25
|
+
expect(exception._binding).to_not be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when exception manager is disabled' do
|
30
|
+
before { manager.disable! }
|
31
|
+
it { is_expected.to be_disabled }
|
32
|
+
|
33
|
+
it 'can be enabled' do
|
34
|
+
manager.enable!
|
35
|
+
expect(manager).to be_enabled
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'does not add local bindings to exceptions' do
|
39
|
+
expect(exception._binding).to be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.add_filters' do
|
45
|
+
before do
|
46
|
+
manager.add_filter do |e|
|
47
|
+
!e.is_a?(CannotDeliverMessageError)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'adds filters for tracepoint' do
|
52
|
+
expect(exception).to be_a(CannotDeliverMessageError)
|
53
|
+
expect(exception._binding).to be_nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ExceptionManager::Methods::Locals do
|
4
|
+
let(:command) { described_class }
|
5
|
+
let(:exception_binding) { a = 1; binding }
|
6
|
+
|
7
|
+
describe '.run' do
|
8
|
+
let(:expected) { { a: 1 } }
|
9
|
+
subject(:result) { command.run(exception_binding) }
|
10
|
+
it { is_expected.to eq(expected) }
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ExceptionManager::Methods::SubjectClassVariables do
|
4
|
+
let(:command) { described_class }
|
5
|
+
|
6
|
+
let(:klass) do
|
7
|
+
Class.new do
|
8
|
+
self.class_variable_set(:@@a, 1)
|
9
|
+
|
10
|
+
def local_binding
|
11
|
+
binding
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:exception_binding) { klass.new.local_binding }
|
17
|
+
|
18
|
+
describe '.run' do
|
19
|
+
subject { command.run(exception_binding) }
|
20
|
+
let(:expected) { { :@@a => 1 } }
|
21
|
+
it { is_expected.to eq(expected) }
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ExceptionManager::Methods::SubjectInstanceVariables do
|
4
|
+
let(:command) { described_class }
|
5
|
+
|
6
|
+
let(:klass) do
|
7
|
+
Class.new do
|
8
|
+
def local_binding
|
9
|
+
@a = 1
|
10
|
+
binding
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:exception_binding) { klass.new.local_binding }
|
16
|
+
|
17
|
+
describe '.run' do
|
18
|
+
subject(:result) { command.run(exception_binding) }
|
19
|
+
let(:expected) { { :@a => 1 } }
|
20
|
+
it { is_expected.to eq(expected) }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ExceptionManager::Methods::Subject do
|
4
|
+
let(:command) { described_class }
|
5
|
+
|
6
|
+
let(:klass) do
|
7
|
+
Class.new do
|
8
|
+
def self.local_binding
|
9
|
+
binding
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:exception_binding) do
|
15
|
+
klass.local_binding
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '.run' do
|
19
|
+
subject(:result) { command.run(exception_binding) }
|
20
|
+
it { is_expected.to eq(klass) }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ExceptionManager do
|
4
|
+
subject(:error) do
|
5
|
+
begin
|
6
|
+
Letter.new('message', 'from@example.com').deliver_to('to@example.com')
|
7
|
+
rescue => e
|
8
|
+
e
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'Kernel.raise' do
|
13
|
+
it 'still raises exception' do
|
14
|
+
expect { raise 'foo' }.to raise_error
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'Exception#locals' do
|
19
|
+
let(:expected) do
|
20
|
+
{
|
21
|
+
exception_message: "'to@example.com' does not want to receive emails from you",
|
22
|
+
recipient: 'to@example.com'
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns Hash of local variables available when #raise happened' do
|
27
|
+
expect(error.locals).to eq(expected)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'Exception#subject' do
|
32
|
+
it 'returns context of place when subject was raised' do
|
33
|
+
expect(error.subject).to be_a(Letter)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'Exception#subject_instance_variables' do
|
38
|
+
let(:expected) do
|
39
|
+
{
|
40
|
+
:@message => 'message',
|
41
|
+
:@sender => 'from@example.com'
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'returns instance variables of #subject when #raise happened' do
|
46
|
+
expect(error.subject_instance_variables).to eq(expected)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'Exception#subject_class_variables' do
|
51
|
+
let(:expected) do
|
52
|
+
{
|
53
|
+
:@@class_variable => 'class variable'
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'returns class variables of #subject when #raise happened' do
|
58
|
+
expect(error.subject_class_variables).to eq(expected)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'Exception#summary' do
|
63
|
+
let(:expected) do
|
64
|
+
{
|
65
|
+
locals: instance_of(Hash),
|
66
|
+
subject: instance_of(Letter),
|
67
|
+
subject_instance_variables: instance_of(Hash),
|
68
|
+
subject_class_variables: instance_of(Hash)
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'returns all available information combined into single Hash' do
|
73
|
+
expect(error.summary).to be_a(Hash)
|
74
|
+
|
75
|
+
expect(error.summary[:locals]).to be_a(Hash)
|
76
|
+
expect(error.summary[:subject]).to be_a(Letter)
|
77
|
+
expect(error.summary[:subject_instance_variables]).to be_a(Hash)
|
78
|
+
expect(error.summary[:subject_class_variables]).to be_a(Hash)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
ROOT = Pathname.new(File.expand_path('../..', __FILE__))
|
2
|
+
$: << ROOT
|
3
|
+
require 'exception_manager'
|
4
|
+
require 'pry'
|
5
|
+
require 'rspec/its'
|
6
|
+
|
7
|
+
Dir[ROOT.join('spec/support/**/*.rb')].each { |f| require f }
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.expect_with :rspec do |expectations|
|
11
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
12
|
+
end
|
13
|
+
|
14
|
+
config.mock_with :rspec do |mocks|
|
15
|
+
mocks.verify_partial_doubles = true
|
16
|
+
end
|
17
|
+
|
18
|
+
config.before(:suite) do
|
19
|
+
ExceptionManager.enable!
|
20
|
+
end
|
21
|
+
|
22
|
+
config.order = :random
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# @example
|
2
|
+
# letter = Letter.new('message', 'sender@example.com')
|
3
|
+
# letter.deliver_to('recipient@example.com')
|
4
|
+
#
|
5
|
+
# CannotDeliverMessageError: 'recipient@example.com' does not want to receive emails from you
|
6
|
+
#
|
7
|
+
CannotDeliverMessageError = Class.new(StandardError)
|
8
|
+
|
9
|
+
class Letter
|
10
|
+
attr_reader :message, :sender
|
11
|
+
@@class_variable = 'class variable'
|
12
|
+
|
13
|
+
def initialize(message, sender)
|
14
|
+
@message = message
|
15
|
+
@sender = sender
|
16
|
+
end
|
17
|
+
|
18
|
+
def deliver_to(recipient)
|
19
|
+
exception_message = "'#{recipient}' does not want to receive emails from you"
|
20
|
+
raise CannotDeliverMessageError, exception_message
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ResetConfigHelper
|
2
|
+
def self.included(base)
|
3
|
+
base.instance_eval do
|
4
|
+
around(:each) do |example|
|
5
|
+
example.run
|
6
|
+
ExceptionManager.reset_filters!
|
7
|
+
ExceptionManager.enable!
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.include ResetConfigHelper
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: exception_manager
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ilya Bylich
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.2.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.2.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-its
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.2.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.2.0
|
69
|
+
description: Gem for inspecting local and class/instance variables when raising exceptions
|
70
|
+
email:
|
71
|
+
- ibylich@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .rspec
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- exception_manager.gemspec
|
83
|
+
- lib/exception_manager.rb
|
84
|
+
- lib/exception_manager/config.rb
|
85
|
+
- lib/exception_manager/methods/locals.rb
|
86
|
+
- lib/exception_manager/methods/subject.rb
|
87
|
+
- lib/exception_manager/methods/subject_class_variables.rb
|
88
|
+
- lib/exception_manager/methods/subject_instance_variables.rb
|
89
|
+
- lib/exception_manager/patch.rb
|
90
|
+
- lib/exception_manager/version.rb
|
91
|
+
- spec/exception_manager/config_spec.rb
|
92
|
+
- spec/exception_manager/methods/locals_spec.rb
|
93
|
+
- spec/exception_manager/methods/subject_class_variables_spec.rb
|
94
|
+
- spec/exception_manager/methods/subject_instance_variables_spec.rb
|
95
|
+
- spec/exception_manager/methods/subject_spec.rb
|
96
|
+
- spec/exception_manager/patch_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
- spec/support/exception_examples/letter.rb
|
99
|
+
- spec/support/helpers/reset_config_helper.rb
|
100
|
+
homepage: ''
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.4.3
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: Tool for managing exceptions
|
124
|
+
test_files:
|
125
|
+
- spec/exception_manager/config_spec.rb
|
126
|
+
- spec/exception_manager/methods/locals_spec.rb
|
127
|
+
- spec/exception_manager/methods/subject_class_variables_spec.rb
|
128
|
+
- spec/exception_manager/methods/subject_instance_variables_spec.rb
|
129
|
+
- spec/exception_manager/methods/subject_spec.rb
|
130
|
+
- spec/exception_manager/patch_spec.rb
|
131
|
+
- spec/spec_helper.rb
|
132
|
+
- spec/support/exception_examples/letter.rb
|
133
|
+
- spec/support/helpers/reset_config_helper.rb
|