exception_details 0.0.1
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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +89 -0
- data/Rakefile +1 -0
- data/exception_details.gemspec +27 -0
- data/lib/exception_details.rb +6 -0
- data/lib/exception_details/exception.rb +53 -0
- data/lib/exception_details/inspect_variables.rb +50 -0
- data/lib/exception_details/log_color_helpers.rb +23 -0
- data/lib/exception_details/version.rb +3 -0
- data/spec/exception_details_spec.rb +107 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/variable_scope_test_object.rb +24 -0
- metadata +129 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Eric Beland
|
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,89 @@
|
|
1
|
+
# Exception Details
|
2
|
+
|
3
|
+
Exception Details causes instances of Exception to capture a binding at creation-time.
|
4
|
+
It provides convenience methods on Exceptions to inspect all the variables and values
|
5
|
+
from the time of the Exception and adds an informative log string.
|
6
|
+
|
7
|
+
Features/benefits:
|
8
|
+
|
9
|
+
* Get detail (variables/values) about your Exception circumstances *without* reproducing the problem first.
|
10
|
+
|
11
|
+
* Reduced need for debug/logging code to find out what went wrong.
|
12
|
+
|
13
|
+
* Minimize ambiguous errors (which variable was nil?).
|
14
|
+
|
15
|
+
* A single statement method for a loggable string (avoid repeating exception log string creation)
|
16
|
+
|
17
|
+
* Get Pry like debug knowledge from cron job errors and running system logs without being there.
|
18
|
+
|
19
|
+
* Pry type information with less overhead/dependencies--binding_of_caller is the only dependency.
|
20
|
+
|
21
|
+
|
22
|
+
## Example Usage
|
23
|
+
|
24
|
+
begin
|
25
|
+
greeting = 'hello'
|
26
|
+
@name = nil
|
27
|
+
puts greeting + name
|
28
|
+
rescue Exception => e
|
29
|
+
puts e.details
|
30
|
+
puts e.inspect_variables
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
e.details ->
|
35
|
+
|
36
|
+
Exception:
|
37
|
+
can't convert nil into String
|
38
|
+
Variables:
|
39
|
+
<String>greeting = "hello"
|
40
|
+
<TypeError>e = #<TypeError: can't convert nil into String>
|
41
|
+
<NilClass>@name = nil
|
42
|
+
Backtrace:
|
43
|
+
/Users/someguy/apps/exception_details/spec/exception_details_spec.rb:20:in `+'
|
44
|
+
/Users/someguy/apps/exception_details/spec/exception_details_spec.rb:20:in `block (3 levels) in <top (required)>'
|
45
|
+
/Users/someguy/.rvm/gems/ruby-1.9.3-p374/gems/rspec-core-2.14.3/lib/rspec/core/example.rb:114:in `instance_eval'
|
46
|
+
and so forth ...
|
47
|
+
|
48
|
+
|
49
|
+
e.inspect_variables ->
|
50
|
+
|
51
|
+
<String>greeting = "hello"
|
52
|
+
<TypeError>e = #<TypeError: can't convert nil into String>
|
53
|
+
<NilClass>@name = nil
|
54
|
+
|
55
|
+
Or access the variables in the binding yourself...
|
56
|
+
|
57
|
+
e.binding_during_exception.eval("puts #{greeting}")
|
58
|
+
|
59
|
+
## Installation
|
60
|
+
|
61
|
+
Add to your Gemfile:
|
62
|
+
|
63
|
+
gem 'exception_details'
|
64
|
+
|
65
|
+
Execute:
|
66
|
+
|
67
|
+
$ bundle
|
68
|
+
|
69
|
+
Require it:
|
70
|
+
|
71
|
+
require 'exception_details'
|
72
|
+
|
73
|
+
## Limitations
|
74
|
+
- This gem requires [binding\_of\_caller]:https://github.com/banister/binding_of_caller, so it should only work with MRI 1.9.2, 1.9.3, 2.0
|
75
|
+
and RBX (Rubinius). Does not work in 1.8.7, but there is a well known (continuation-based)
|
76
|
+
hack to get a Binding#of_caller there. There is some mention about binding of caller supporting
|
77
|
+
jruby, so feel free to try it out.
|
78
|
+
|
79
|
+
- Getting a binding from a NameError seems to be problematic.
|
80
|
+
|
81
|
+
- This gem is still new...
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
1. Fork it
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
87
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
88
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -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 'exception_details/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "exception_details"
|
8
|
+
spec.version = ExceptionDetails::VERSION
|
9
|
+
spec.authors = ["Eric Beland"]
|
10
|
+
spec.email = ["ebeland@gmail.com"]
|
11
|
+
spec.description = %q{Inspect variables captured at exception-time to get info about your exceptions}
|
12
|
+
spec.summary = %q{Exception Details extends Exception to let you inspect variable values at exception-time for logging etc.}
|
13
|
+
spec.homepage = "https://github.com/ericbeland/exception_details"
|
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_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
|
25
|
+
spec.add_dependency "binding_of_caller"
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative '../exception_details'
|
2
|
+
|
3
|
+
# Extend the Ruby Exception class with our helper methods.
|
4
|
+
class Exception
|
5
|
+
include ExceptionDetails::InspectVariables
|
6
|
+
include ExceptionDetails::LogColorHelpers
|
7
|
+
|
8
|
+
# binding_during_exception lets you actually directly access
|
9
|
+
# the exception-time binding.
|
10
|
+
attr_accessor :binding_during_exception
|
11
|
+
|
12
|
+
# Provides a string with the variable names and values
|
13
|
+
# captured at exception time.
|
14
|
+
def inspect_variables(opts = {})
|
15
|
+
variable_inspect_string(binding_during_exception, opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
# .details provides a fairly complete string for logging purposes.
|
19
|
+
# The message, variables in the exception's scope, and their current
|
20
|
+
# values are outputted, followed by the whole backtrace.
|
21
|
+
# * +options+ - options[:scope] default: [:local_variables, :instance_variables, :class_variables]
|
22
|
+
# - options[:colorize] true / false. Whether to add color to the output (for terminal/log)
|
23
|
+
def details(options = {})
|
24
|
+
options = {colorize: true}.merge(options)
|
25
|
+
inspect_results = inspect_variables(options)
|
26
|
+
parts = []
|
27
|
+
parts << (options[:colorize] ? red('Exception:') : 'Exception:')
|
28
|
+
parts << "\t" + message
|
29
|
+
parts << (options[:colorize] ? red('Variables:') : 'Variables:')
|
30
|
+
parts << inspect_results
|
31
|
+
parts << (options[:colorize] ? red('Backtrace:') : 'Backtrace:')
|
32
|
+
parts << "\t" + backtrace.to_a.join("\n")
|
33
|
+
parts.join("\n")
|
34
|
+
end
|
35
|
+
|
36
|
+
class << self
|
37
|
+
alias :__new__ :new
|
38
|
+
|
39
|
+
def inherited(subclass)
|
40
|
+
class << subclass
|
41
|
+
alias :new :__new__
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# override the .new method on exception to grab the binding where the exception occurred.
|
47
|
+
def self.new(*args, &block)
|
48
|
+
e = __new__(*args)
|
49
|
+
e.binding_during_exception = binding.of_caller(1)
|
50
|
+
e
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ExceptionDetails
|
2
|
+
|
3
|
+
# Mixin that provides methods for dumping variables
|
4
|
+
module InspectVariables
|
5
|
+
|
6
|
+
SCOPES = [:local_variables, :instance_variables, :class_variables]
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# For each variable scope, build an array of strings displaying
|
11
|
+
# type, name and value of each variable in that scope
|
12
|
+
# * +target_binding+ - Binding context to inspect.
|
13
|
+
# * +variable_scope+ - Variable scope to dump. One of :local_variables,
|
14
|
+
# :instance_variables, :class_variables, :global variables
|
15
|
+
|
16
|
+
def dump_variables(target_binding, variable_scope)
|
17
|
+
variable_strings = []
|
18
|
+
if target_binding.eval("respond_to?(:#{variable_scope}, true)")
|
19
|
+
variable_names = target_binding.eval(variable_scope.to_s)
|
20
|
+
variable_names.each do |vname|
|
21
|
+
value = target_binding.eval(vname.to_s)
|
22
|
+
variable_value_string = "\t<#{value.class}>#{vname} = #{value.inspect}"
|
23
|
+
variable_strings << variable_value_string
|
24
|
+
end
|
25
|
+
end
|
26
|
+
variable_strings.sort
|
27
|
+
end
|
28
|
+
|
29
|
+
# Dump all variables and values in selected scopes into a string
|
30
|
+
# * +target_binding+ - Binding context to inspect.
|
31
|
+
# * +options+ - options[:scope] default: [:local_variables, :instance_variables, :class_variables]
|
32
|
+
# - :global_variables is valid as well. Can be an array, or single scope-name symbol
|
33
|
+
# or an array
|
34
|
+
def variable_inspect_string(target_binding, options = {})
|
35
|
+
if options[:scopes]
|
36
|
+
scopes = [options[:scopes]].flatten
|
37
|
+
end
|
38
|
+
return ["exception_details: Variable inspection unavailable (no binding captured)"] if target_binding.nil?
|
39
|
+
variable_scopes = scopes || SCOPES
|
40
|
+
dump_arrays = []
|
41
|
+
variable_scopes.each do |variable_scope|
|
42
|
+
variable_string_array = dump_variables(target_binding, variable_scope.to_s)
|
43
|
+
dump_arrays << variable_string_array if variable_string_array.length > 0
|
44
|
+
end
|
45
|
+
dump_arrays.join("\n")
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Helper methods for printing colored output into the log/terminal
|
2
|
+
module ExceptionDetails
|
3
|
+
module LogColorHelpers
|
4
|
+
def black(str); "\033[30m#{str}\033[0m" end
|
5
|
+
def red(str); "\033[31m#{str}\033[0m" end
|
6
|
+
def green(str); "\033[32m#{str}\033[0m" end
|
7
|
+
def brown(str); "\033[33m#{str}\033[0m" end
|
8
|
+
def blue(str); "\033[34m#{str}\033[0m" end
|
9
|
+
def magenta(str); "\033[35m#{str}\033[0m" end
|
10
|
+
def cyan(str); "\033[36m#{str}\033[0m" end
|
11
|
+
def gray(str); "\033[37m#{str}\033[0m" end
|
12
|
+
def bg_black(str); "\033[40m#{str}\0330m" end
|
13
|
+
def bg_red(str); "\033[41m#{str}\033[0m" end
|
14
|
+
def bg_green(str); "\033[42m#{str}\033[0m" end
|
15
|
+
def bg_brown(str); "\033[43m#{str}\033[0m" end
|
16
|
+
def bg_blue(str); "\033[44m#{str}\033[0m" end
|
17
|
+
def bg_magenta(str); "\033[45m#{str}\033[0m" end
|
18
|
+
def bg_cyan(str); "\033[46m#{str}\033[0m" end
|
19
|
+
def bg_gray(str); "\033[47m#{str}\033[0m" end
|
20
|
+
def bold(str); "\033[1m#{str}\033[22m" end
|
21
|
+
def reverse_color(str); "\033[7m#{str}\033[27m" end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
require 'exception_details'
|
4
|
+
|
5
|
+
describe "ExceptionDetails" do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
v = VariableScopeTestObject.new
|
9
|
+
@e = v.make_exception
|
10
|
+
@class_e = VariableScopeTestObject.make_class_level_exception
|
11
|
+
end
|
12
|
+
|
13
|
+
context ".details" do
|
14
|
+
it "should provide exception details method with back trace" do
|
15
|
+
@e.details.include?('.rb').should be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should provide exception message" do
|
19
|
+
@e.details.include?(@e.message).should be_true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should include inspect_variables output" do
|
23
|
+
@e.details.include?(@e.inspect_variables).should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
context "exception detail functions" do
|
29
|
+
|
30
|
+
it "should be available on exceptions created by raise and a string" do
|
31
|
+
begin
|
32
|
+
raise "Foo"
|
33
|
+
rescue Exception => e
|
34
|
+
e.binding_during_exception.should be_an_instance_of Binding
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be available on Exceptions" do
|
39
|
+
reality_check = true
|
40
|
+
e = Exception.new
|
41
|
+
e.binding_during_exception.should be_an_instance_of Binding
|
42
|
+
e.inspect_variables.include?("reality_check").should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should be available on subclasses of exception like Standard Error" do
|
46
|
+
reality_check = true
|
47
|
+
e = StandardError.new
|
48
|
+
e.binding_during_exception.should be_an_instance_of Binding
|
49
|
+
e.inspect_variables.include?("reality_check").should be_true
|
50
|
+
# end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should be available on grandchild subclasses" do
|
54
|
+
begin
|
55
|
+
# cause an arugument error
|
56
|
+
should_be_in_output = true
|
57
|
+
"UP".downcase("", "")
|
58
|
+
rescue Exception => e
|
59
|
+
e.binding_during_exception.should be_an_instance_of Binding
|
60
|
+
e.inspect_variables.include?("should_be_in_output").should be_true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
pending "Need to investigate why NameError won't capture a binding (any takers?)" do
|
65
|
+
it "should capture a binding for NameError" do
|
66
|
+
begin
|
67
|
+
reality_check = true
|
68
|
+
'hello' + made_up_variable
|
69
|
+
rescue Exception =>e
|
70
|
+
e.binding_during_exception.should be_an_instance_of Binding
|
71
|
+
e.inspect_variables.include?("reality_check").should be_true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
context "inspect variables" do
|
79
|
+
|
80
|
+
it "should include variable values" do
|
81
|
+
@e.inspect_variables.include?('1nstance').should be_true
|
82
|
+
@e.inspect_variables.include?('1ocal').should be_true
|
83
|
+
|
84
|
+
@class_e.inspect_variables.include?('c1ass').should be_true
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should include variable names" do
|
88
|
+
names = %w{@instance local @@class}
|
89
|
+
@e.inspect_variables.include?('@instance').should be_true
|
90
|
+
@e.inspect_variables.include?('local').should be_true
|
91
|
+
|
92
|
+
@class_e.inspect_variables.include?('@@class').should be_true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not include global variables by default" do
|
96
|
+
@e.details.include?('g1obal').should be_false
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should let me select scopes" do
|
100
|
+
d = @e.details(:scopes => :local_variables)
|
101
|
+
@e.details(:scopes => :local_variables).include?('1nstance').should be_false
|
102
|
+
@e.details(:scopes => :class_variables).include?('g1obal').should be_false
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'exception_details'
|
5
|
+
require 'variable_scope_test_object'
|
6
|
+
|
7
|
+
# Requires supporting files with custom matchers and macros, etc,
|
8
|
+
# in ./support/ and its subdirectories.
|
9
|
+
Dir["#{File.dirname(__FILE__)}/helpers/**/*.rb"].each {|f| require f }
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class VariableScopeTestObject
|
2
|
+
|
3
|
+
@@class = 'c1ass'
|
4
|
+
$global = 'g1obal'
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@instance = '1nstance'
|
8
|
+
end
|
9
|
+
|
10
|
+
def make_exception
|
11
|
+
local = '1ocal'
|
12
|
+
e = Exception.new("Foo")
|
13
|
+
e.set_backtrace(['somemadeupfileforbacktrace.rb:435'])
|
14
|
+
e
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.make_class_level_exception
|
18
|
+
local = '1ocal'
|
19
|
+
e = Exception.new("Foo")
|
20
|
+
e.set_backtrace(['somemadeupfileforbacktrace.rb:435'])
|
21
|
+
e
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: exception_details
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Eric Beland
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: binding_of_caller
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Inspect variables captured at exception-time to get info about your exceptions
|
79
|
+
email:
|
80
|
+
- ebeland@gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- Gemfile
|
87
|
+
- LICENSE.txt
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- exception_details.gemspec
|
91
|
+
- lib/exception_details.rb
|
92
|
+
- lib/exception_details/exception.rb
|
93
|
+
- lib/exception_details/inspect_variables.rb
|
94
|
+
- lib/exception_details/log_color_helpers.rb
|
95
|
+
- lib/exception_details/version.rb
|
96
|
+
- spec/exception_details_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
- spec/variable_scope_test_object.rb
|
99
|
+
homepage: https://github.com/ericbeland/exception_details
|
100
|
+
licenses:
|
101
|
+
- MIT
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 1.8.25
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Exception Details extends Exception to let you inspect variable values at
|
124
|
+
exception-time for logging etc.
|
125
|
+
test_files:
|
126
|
+
- spec/exception_details_spec.rb
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- spec/variable_scope_test_object.rb
|
129
|
+
has_rdoc:
|