pry-exception_explorer 0.1.9 → 0.2.0pre1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -7,7 +7,10 @@ _Enter the context of exceptions_
7
7
 
8
8
  `pry-exception_explorer` is an interactive error console for MRI Ruby 1.9.2+ inspired by the [Hammertime](https://github.com/avdi/hammertime)
9
9
  gem, which was in turn inspired by consoles found in the Lisp and Smalltalk environments. `pry-exception_explorer` is a plugin
10
- for the [Pry REPL](http://pry.github.com).
10
+ for the [Pry REPL](http://pry.github.com).
11
+
12
+ **Note**, like the hammertime gem, `pry-exception_explorer` can only really intercept exceptions that are explicitly raised (using the `raise` method) from Ruby code.
13
+ This means that exceptions raised by syntax errors or from code such as `1/0` cannot be intercepted. Though experimental support for intercepting such deep (c-level) exceptions is provided by invoking with `pry --c-exceptions`.
11
14
 
12
15
  Using `pry-exception_explorer` we can automatically pull up a [Pry](http://pry.github.com) session at the point an exception arises and use `Pry`
13
16
  to inspect the state there to debug (and fix) the problem. We also get access to the entire call stack of the exception and can walk the stack to interactively examine the state in
@@ -18,7 +21,9 @@ parent frames (using [pry-stack_explorer](https://github.com/pry/pry-stack_explo
18
21
  * Install the [gem](https://rubygems.org/gems/pry-exception_explorer): `gem install pry-exception_explorer`
19
22
  * Read the [documentation](http://rdoc.info/github/banister/pry-exception_explorer/master/file/README.md)
20
23
  * See the [source code](http://github.com/banister/pry-exception_explorer)
21
- * See the [wiki](https://github.com/pry/pry-exception_explorer/wiki) for in-depth usage information.
24
+ * See the [**WIKI**](https://github.com/pry/pry-exception_explorer/wiki) for in-depth usage information.
25
+
26
+ Also look at the [plymouth](https://github.com/banister/plymouth) project which utilizes `pry-exception_explorer` to intercept test failures.
22
27
 
23
28
  Example:
24
29
  --------
data/Rakefile CHANGED
@@ -23,7 +23,7 @@ def apply_spec_defaults(s)
23
23
  s.description = s.summary
24
24
  s.require_path = 'lib'
25
25
  s.homepage = "https://github.com/banister/pry-exception_explorer"
26
- s.add_dependency('pry-stack_explorer', ">=0.3.9")
26
+ s.add_dependency('pry-stack_explorer', ">=0.4.6")
27
27
  s.add_development_dependency("bacon","~>1.1.0")
28
28
  s.add_development_dependency('rake', '~> 0.9')
29
29
  s.executables = ['pry-shim']
@@ -68,7 +68,7 @@ end
68
68
 
69
69
  desc "run tests"
70
70
  task :test do
71
- sh "bacon -Itest -rubygems -a -q"
71
+ sh "bacon -Itest -rubygems -a -q"
72
72
  end
73
73
 
74
74
  desc "Build gemspec"
data/bin/pry-shim CHANGED
File without changes
@@ -5,8 +5,13 @@ module PryExceptionExplorer
5
5
  include PryStackExplorer::FrameHelpers
6
6
 
7
7
  private
8
+
9
+ def exception
10
+ frame_manager.user[:exception]
11
+ end
12
+
8
13
  def in_exception?
9
- frame_manager && frame_manager.user[:exception]
14
+ frame_manager && exception
10
15
  end
11
16
 
12
17
  def last_exception
@@ -14,17 +19,20 @@ module PryExceptionExplorer
14
19
  end
15
20
 
16
21
  def enterable_exception?
17
- last_exception && last_exception.exception_call_stack
22
+ PryExceptionExplorer.enabled && last_exception && last_exception.exception_call_stack
18
23
  end
19
24
 
20
25
  def inline_exception?
21
- frame_manager && frame_manager.user[:exception] &&
26
+ in_exception? &&
22
27
  frame_manager.user[:inline_exception]
23
28
  end
24
29
 
30
+ def internal_exception?
31
+ in_exception? && exception.internal_exception?
32
+ end
33
+
25
34
  def normal_exception?
26
- frame_manager && frame_manager.user[:exception] &&
27
- frame_manager.user[:exception].continuation
35
+ in_exception? && frame_manager.user[:exception].continuation
28
36
  end
29
37
  end
30
38
 
@@ -84,7 +92,9 @@ module PryExceptionExplorer
84
92
  BANNER
85
93
 
86
94
  def process
87
- if inline_exception?
95
+ if internal_exception?
96
+ raise Pry::CommandError, "Internal exceptions (C-level exceptions) cannot be continued!"
97
+ elsif inline_exception?
88
98
  PryStackExplorer.pop_frame_manager(_pry_)
89
99
  run "exit-all PryExceptionExplorer::CONTINUE_INLINE_EXCEPTION"
90
100
  elsif normal_exception?
@@ -16,6 +16,11 @@ class Exception
16
16
  # (Only relevant for wrapped exceptions).
17
17
  attr_accessor :should_intercept
18
18
 
19
+ # @return [Boolean] Whether this exception was raised internally.
20
+ # i.e from the C-level using `rb_raise`
21
+ attr_accessor :internal_exception
22
+ alias_method :internal_exception?, :internal_exception
23
+
19
24
  # This method enables us to continue an exception (using
20
25
  # `callcc` internally)
21
26
  def continue
@@ -23,6 +28,33 @@ class Exception
23
28
  continuation.call
24
29
  end
25
30
 
31
+ alias_method :old_exception, :exception
32
+
33
+ def exception(*args, &block)
34
+ $e = binding.callers.drop(1)
35
+ if PryExceptionExplorer.enabled? &&
36
+ PryExceptionExplorer.should_intercept_exception?(binding.of_caller(1), self) &&
37
+ !caller.any? { |t| t.include?("raise") } && !exception_call_stack
38
+
39
+ ex = old_exception(*args, &block)
40
+
41
+ ex.exception_call_stack = binding.callers.drop(1)
42
+ ex.set_backtrace(caller.drop(1)) if !ex.backtrace
43
+
44
+ PryExceptionExplorer.amend_exception_call_stack!(ex)
45
+ ex.should_intercept = true
46
+ ex.internal_exception = true
47
+
48
+ if PryExceptionExplorer.inline?
49
+ retval = PryExceptionExplorer.enter_exception(ex, :inline => true)
50
+ end
51
+
52
+ ex
53
+ else
54
+ old_exception(*args, &block)
55
+ end
56
+ end
57
+
26
58
  alias_method :should_intercept?, :should_intercept
27
59
  end
28
60
 
@@ -71,18 +103,14 @@ module PryExceptionExplorer
71
103
 
72
104
  intercept_object = PryExceptionExplorer.intercept_object
73
105
 
74
- # FIXME: CodeRay stuff is a hack because CodeRay generates a bunch of
75
- # exceptions that would cause EE to infiniloop on
76
- # intercept(Exception), find a better solution.
77
- if PryExceptionExplorer.should_intercept_exception?(binding.of_caller(1), ex) &&
78
- binding.of_caller(1).eval('[__method__, self.to_s]') != [:make_plugin_hash, "CodeRay::Encoders"]
106
+ if PryExceptionExplorer.should_intercept_exception?(binding.of_caller(1), ex)
79
107
 
80
108
  ex.exception_call_stack = binding.callers.tap { |v| v.shift(1 + intercept_object.skip_num) }
81
109
  PryExceptionExplorer.amend_exception_call_stack!(ex)
82
110
 
83
111
  ex.should_intercept = true
84
112
 
85
- if !PryExceptionExplorer.wrap_active?
113
+ if PryExceptionExplorer.inline?
86
114
  retval = PryExceptionExplorer.enter_exception(ex, :inline => true)
87
115
  end
88
116
  end
@@ -97,7 +125,6 @@ module PryExceptionExplorer
97
125
  end
98
126
  end
99
127
 
100
-
101
128
  class Object
102
129
  include PryExceptionExplorer::CoreExtensions
103
130
  end
@@ -1,3 +1,3 @@
1
1
  module PryExceptionExplorer
2
- VERSION = "0.1.9"
2
+ VERSION = "0.2.0pre1"
3
3
  end
@@ -27,6 +27,19 @@ module PryExceptionExplorer
27
27
  @hash ||= {}
28
28
  end
29
29
 
30
+ # @return [Boolean] Whether exceptions are to be intercepted
31
+ # inline (at the raise site).
32
+ attr_accessor :inline
33
+ attr_accessor :post_mortem
34
+
35
+ # Ensure exceptions are intercepted at the raise site.
36
+ def inline!
37
+ self.inline = true
38
+ end
39
+
40
+ alias_method :inline?, :inline
41
+ alias_method :post_mortem?, :post_mortem
42
+
30
43
  # Enable Exception Explorer.
31
44
  # @return [Boolean]
32
45
  def enable!
@@ -71,8 +84,10 @@ module PryExceptionExplorer
71
84
  # @yield The block to wrap.
72
85
  def wrap
73
86
  old_enabled, old_wrap_active = enabled, wrap_active
87
+ old_inline = inline
74
88
  self.enabled = true
75
89
  self.wrap_active = true
90
+ self.inline = false
76
91
  yield
77
92
  rescue Exception => ex
78
93
  if ex.should_intercept?
@@ -83,6 +98,7 @@ module PryExceptionExplorer
83
98
  ensure
84
99
  self.enabled = old_enabled
85
100
  self.wrap_active = old_wrap_active
101
+ self.inline = old_inline
86
102
  end
87
103
 
88
104
  # This method allows the user to assert the situations where an
@@ -134,7 +150,13 @@ module PryExceptionExplorer
134
150
  # @param [Exception] ex The exception that was raised.
135
151
  # @return [Boolean] Whether the exception should be intercepted.
136
152
  def should_intercept_exception?(frame, ex)
137
- if intercept_object
153
+ # special case, or we go into infinite loop. CodeRay uses
154
+ # exceptions for flow control :/
155
+ if defined?(CodeRay::Encoders) && frame.eval('self') == CodeRay::Encoders
156
+ false
157
+
158
+ # normal case
159
+ elsif intercept_object
138
160
  intercept_object.call(LazyFrame.new(frame), ex)
139
161
  else
140
162
  false
@@ -174,8 +196,8 @@ module PryExceptionExplorer
174
196
  # @option options [Boolean] :inline Whether the exception is being
175
197
  # entered inline (i.e within the `raise` method itself)
176
198
  def setup_exception_context(ex, _pry_, options={})
177
- _pry_.last_exception = ex
178
- _pry_.backtrace = ex.backtrace
199
+ _pry_.last_exception = ex
200
+ _pry_.backtrace = (ex.backtrace || [])
179
201
 
180
202
  PryStackExplorer.frame_manager(_pry_).user[:exception] = ex
181
203
  PryStackExplorer.frame_manager(_pry_).user[:inline_exception] = !!options[:inline]
@@ -190,37 +212,47 @@ module PryExceptionExplorer
190
212
  hooks = Pry.config.hooks.dup.add_hook(:before_session, :set_exception_flag) do |_, _, _pry_|
191
213
  setup_exception_context(ex, _pry_, options)
192
214
  end.add_hook(:before_session, :manage_intercept_recurse) do
193
- PryExceptionExplorer.intercept_object.disable! if !PryExceptionExplorer.intercept_object.intercept_recurse?
215
+ PryExceptionExplorer.intercept_object.disable! if PryExceptionExplorer.inline? && !PryExceptionExplorer.intercept_object.intercept_recurse?
194
216
  end.add_hook(:after_session, :manage_intercept_recurse) do
195
217
  PryExceptionExplorer.intercept_object.enable! if !PryExceptionExplorer.intercept_object.active?
196
218
  end
197
219
 
198
- # Pry.load_plugins
199
- # binding.pry # if we have this here and step through with pry-nav sometimes we get segfaults :/
200
-
201
220
  Pry.start binding, :call_stack => ex.exception_call_stack, :hooks => hooks
202
221
  end
203
222
 
204
223
  # Set initial state
205
224
  def init
225
+ PryExceptionExplorer.post_mortem = true
226
+ PryExceptionExplorer.enabled = true
227
+
206
228
  # disable by default (intercept exceptions inline)
207
- PryExceptionExplorer.wrap_active = false
229
+ PryExceptionExplorer.wrap_active = true
208
230
 
209
231
  # default is to capture all exceptions
210
232
  PryExceptionExplorer.intercept { true }
211
233
 
212
234
  # disable by default
213
- PryExceptionExplorer.enabled = false
235
+ PryExceptionExplorer.inline = false
236
+ at_exit do
237
+ ex = $!
238
+
239
+ next if !PryExceptionExplorer.post_mortem? || !ex
240
+
241
+ if ex.should_intercept?
242
+ enter_exception(ex)
243
+ else
244
+ raise ex
245
+ end
246
+ end
214
247
  end
215
248
  end
216
249
  end
217
250
 
218
251
  # Add a hook to enable EE when invoked via `pry` executable
219
252
  Pry.config.hooks.add_hook(:when_started, :try_enable_exception_explorer) do
220
- if Pry.cli
221
- PryExceptionExplorer.wrap_active = true
222
- PryExceptionExplorer.enabled = true
223
- end
253
+ PryExceptionExplorer.wrap_active = true
254
+ PryExceptionExplorer.enabled = true
255
+ PryExceptionExplorer.inline = false
224
256
  end
225
257
 
226
258
  # Bring in commands
@@ -2,18 +2,18 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "pry-exception_explorer"
5
- s.version = "0.1.9"
5
+ s.version = "0.2.0pre1"
6
6
 
7
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["John Mair (banisterfiend)"]
9
- s.date = "2012-02-21"
9
+ s.date = "2012-09-29"
10
10
  s.description = "Enter the context of exceptions"
11
11
  s.email = "jrmair@gmail.com"
12
12
  s.executables = ["pry-shim"]
13
13
  s.files = [".gemtest", ".gitignore", ".travis.yml", ".yardopts", "CHANGELOG", "Gemfile", "LICENSE", "README.md", "Rakefile", "bin/pry-shim", "examples/example_c_inline.rb", "examples/example_inline.rb", "examples/example_wrap.rb", "lib/pry-exception_explorer.rb", "lib/pry-exception_explorer/cli.rb", "lib/pry-exception_explorer/commands.rb", "lib/pry-exception_explorer/core_ext.rb", "lib/pry-exception_explorer/intercept.rb", "lib/pry-exception_explorer/lazy_frame.rb", "lib/pry-exception_explorer/shim_builder.rb", "lib/pry-exception_explorer/version.rb", "pry-exception_explorer.gemspec", "test/helper.rb", "test/test_exceptions_in_pry.rb", "test/test_inline_exceptions.rb", "test/test_raise.rb", "test/test_wrapped_exceptions.rb"]
14
14
  s.homepage = "https://github.com/banister/pry-exception_explorer"
15
15
  s.require_paths = ["lib"]
16
- s.rubygems_version = "1.8.16"
16
+ s.rubygems_version = "1.8.15"
17
17
  s.summary = "Enter the context of exceptions"
18
18
  s.test_files = ["test/helper.rb", "test/test_exceptions_in_pry.rb", "test/test_inline_exceptions.rb", "test/test_raise.rb", "test/test_wrapped_exceptions.rb"]
19
19
 
@@ -21,16 +21,16 @@ Gem::Specification.new do |s|
21
21
  s.specification_version = 3
22
22
 
23
23
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
24
- s.add_runtime_dependency(%q<pry-stack_explorer>, [">= 0.3.9"])
24
+ s.add_runtime_dependency(%q<pry-stack_explorer>, [">= 0.4.6"])
25
25
  s.add_development_dependency(%q<bacon>, ["~> 1.1.0"])
26
26
  s.add_development_dependency(%q<rake>, ["~> 0.9"])
27
27
  else
28
- s.add_dependency(%q<pry-stack_explorer>, [">= 0.3.9"])
28
+ s.add_dependency(%q<pry-stack_explorer>, [">= 0.4.6"])
29
29
  s.add_dependency(%q<bacon>, ["~> 1.1.0"])
30
30
  s.add_dependency(%q<rake>, ["~> 0.9"])
31
31
  end
32
32
  else
33
- s.add_dependency(%q<pry-stack_explorer>, [">= 0.3.9"])
33
+ s.add_dependency(%q<pry-stack_explorer>, [">= 0.4.6"])
34
34
  s.add_dependency(%q<bacon>, ["~> 1.1.0"])
35
35
  s.add_dependency(%q<rake>, ["~> 0.9"])
36
36
  end
data/test/helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+ require 'pry'
2
3
 
3
4
  unless Object.const_defined? 'PryExceptionExplorer'
4
5
  $:.unshift File.expand_path '../../lib', __FILE__
@@ -17,6 +18,8 @@ class OpenStruct
17
18
  end
18
19
  end
19
20
 
21
+ Pad = OpenStruct.new
22
+
20
23
  class Ratty
21
24
  def ratty
22
25
  Weasel.new.weasel
@@ -15,6 +15,42 @@ describe PryExceptionExplorer do
15
15
  end
16
16
 
17
17
  describe "Exceptions caught by Pry" do
18
+
19
+ describe "internal exceptions (C-level)" do
20
+ before do
21
+ O.klass = Class.new do
22
+ def alpha
23
+ beta
24
+ end
25
+ def beta
26
+ 1 / 0
27
+ end
28
+ end
29
+ end
30
+
31
+ it 'should be able to enter internal exceptions' do
32
+ redirect_pry_io(InputTester.new("O.klass.new.alpha",
33
+ "enter-exception",
34
+ "O.method_name = __method__",
35
+ "exit")) do
36
+ Pry.start
37
+ end
38
+
39
+ O.method_name.should == :beta
40
+ end
41
+
42
+ it 'should have the full call-stack available' do
43
+ redirect_pry_io(InputTester.new("O.klass.new.alpha",
44
+ "enter-exception",
45
+ "show-stack",
46
+ "exit"), out=StringIO.new) do
47
+ Pry.start
48
+ end
49
+
50
+ out.string.should =~ /alpha/
51
+ end
52
+ end
53
+
18
54
  describe "enter-exception" do
19
55
  it "should be able to enter an exception caught by pry" do
20
56
  # there are 3 types of situations where exception_explorer is invoked:
@@ -6,6 +6,7 @@ O = OpenStruct.new
6
6
 
7
7
  prev_wrap_state = PryExceptionExplorer.wrap_active
8
8
  PryExceptionExplorer.wrap_active = false
9
+ PryExceptionExplorer.inline!
9
10
 
10
11
  prev_intercept_state = PryExceptionExplorer.intercept_object
11
12
 
@@ -32,6 +33,23 @@ describe PryExceptionExplorer do
32
33
  O.clear
33
34
  end
34
35
 
36
+ describe "internal exceptions" do
37
+ it 'should intercept internal exceptions inline' do
38
+ redirect_pry_io(StringIO.new("O.exception_intercepted = true\nexit-all\n"), out=StringIO.new) do
39
+ (1 / 0) rescue nil
40
+ end
41
+
42
+ O.exception_intercepted.should == true
43
+ end
44
+
45
+ it 'should be un-continuable' do
46
+ redirect_pry_io(StringIO.new("O.exception_intercepted = true\ncontinue-exception\n"), out=StringIO.new) do
47
+ (1 / 0) rescue nil
48
+ end
49
+ out.string.should =~ /cannot be continued/
50
+ end
51
+ end
52
+
35
53
  describe "enabled = false" do
36
54
  it 'should prevent interception of an exception' do
37
55
  old_e = PryExceptionExplorer.enabled
@@ -14,6 +14,7 @@ describe PryExceptionExplorer do
14
14
  end
15
15
 
16
16
  after do
17
+ Pad.clear
17
18
  Pry.config.hooks.delete_hook(:when_started, :save_caller_bindings)
18
19
  Pry.config.hooks.delete_hook(:after_session, :delete_frame_manager)
19
20
  end
@@ -56,11 +57,42 @@ describe PryExceptionExplorer do
56
57
  end
57
58
  end
58
59
 
60
+ describe "internal exceptions" do
61
+ it 'should be able to intercept internal exceptions' do
62
+ redirect_pry_io(InputTester.new("Pad.ex = _ex_", "exit-all")) do
63
+ PryExceptionExplorer.wrap do
64
+ (1 / 0)
65
+ end rescue nil
66
+ end
67
+
68
+ Pad.ex.is_a?(ZeroDivisionError).should == true
69
+ end
70
+
71
+ it 'should not intercept rescued exceptions' do
72
+ redirect_pry_io(InputTester.new("Pad.ex = _ex_", "exit-all")) do
73
+ PryExceptionExplorer.wrap do
74
+ (1 / 0) rescue nil
75
+ end
76
+ end
77
+
78
+ Pad.ex.should == nil
79
+ end
80
+
81
+ it 'should not be able to continue exceptions' do
82
+ redirect_pry_io(InputTester.new("continue-exception"), out=StringIO.new) do
83
+ PryExceptionExplorer.wrap do
84
+ (1 / 0)
85
+ end
86
+ end
87
+
88
+ out.string.should =~ /cannot be continued/
89
+ end
90
+ end
91
+
59
92
  describe "enabled = false" do
60
93
  it 'should have no effect for wrap block (which sets enabled=true internally)' do
61
94
  old_e = PryExceptionExplorer.enabled
62
95
  PryExceptionExplorer.enabled = false
63
-
64
96
  PryExceptionExplorer.wrap do
65
97
  raise CaughtException, "catch me if u can"
66
98
  end.should == :caught
metadata CHANGED
@@ -1,30 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pry-exception_explorer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
5
- prerelease:
4
+ version: 0.2.0pre1
5
+ prerelease: 5
6
6
  platform: ruby
7
7
  authors:
8
8
  - John Mair (banisterfiend)
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-21 00:00:00.000000000 Z
12
+ date: 2012-09-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pry-stack_explorer
16
- requirement: &70215207746240 !ruby/object:Gem::Requirement
16
+ requirement: &70293402053520 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.3.9
21
+ version: 0.4.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70215207746240
24
+ version_requirements: *70293402053520
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bacon
27
- requirement: &70215207745780 !ruby/object:Gem::Requirement
27
+ requirement: &70293401916160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.1.0
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70215207745780
35
+ version_requirements: *70293401916160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &70215207745320 !ruby/object:Gem::Requirement
38
+ requirement: &70293401915540 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0.9'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70215207745320
46
+ version_requirements: *70293401915540
47
47
  description: Enter the context of exceptions
48
48
  email: jrmair@gmail.com
49
49
  executables:
@@ -93,12 +93,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
93
93
  required_rubygems_version: !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
- - - ! '>='
96
+ - - ! '>'
97
97
  - !ruby/object:Gem::Version
98
- version: '0'
98
+ version: 1.3.1
99
99
  requirements: []
100
100
  rubyforge_project:
101
- rubygems_version: 1.8.16
101
+ rubygems_version: 1.8.15
102
102
  signing_key:
103
103
  specification_version: 3
104
104
  summary: Enter the context of exceptions