exception_manager 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .ruby-version
16
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in exception_manager.gemspec
4
+ gemspec
5
+
6
+ gem 'pry'
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,5 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
@@ -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,10 @@
1
+ class ExceptionManager::Methods::Locals
2
+ def self.run(exception_binding)
3
+ exception_binding.eval %q{
4
+ local_variables.inject({}) do |hash, local_variable_name|
5
+ hash[local_variable_name] = eval(local_variable_name.to_s)
6
+ hash
7
+ end
8
+ }
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class ExceptionManager::Methods::Subject
2
+ def self.run(exception_binding)
3
+ exception_binding.eval('self')
4
+ end
5
+ 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,8 @@
1
+ module ExceptionManager
2
+ module Version
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ PATCH = 0
6
+ STRING = [MAJOR, MINOR, PATCH].join('.')
7
+ end
8
+ end
@@ -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
@@ -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