exception_details 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|