pry-rescue 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +7 -29
- data/lib/pry-rescue/commands.rb +2 -2
- data/lib/pry-rescue/core_ext.rb +38 -12
- data/lib/pry-rescue.rb +13 -1
- data/pry-rescue.gemspec +1 -1
- data/spec/core_ext_spec.rb +96 -0
- metadata +3 -2
data/README.md
CHANGED
@@ -1,38 +1,18 @@
|
|
1
1
|
|
2
|
-
**pry-rescue**
|
3
|
-
|
4
|
-
Installation
|
5
|
-
============
|
6
|
-
|
7
|
-
Either `gem install pry-rescue`, or add it to the development section of your Gemfile:
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
source :rubygems
|
11
|
-
group :development do
|
12
|
-
gem 'pry-rescue'
|
13
|
-
gem 'pry-stack_explorer' # if you're using MRI 1.9 and you want it to be awesome.
|
14
|
-
end
|
15
|
-
```
|
2
|
+
**pry-rescue** super-fast, painless, debugging for the (ruby) masses. (See [Pry to the rescue!](https://cirw.in/blog/pry-to-the-rescue))
|
16
3
|
|
17
4
|
Usage
|
18
5
|
=====
|
19
6
|
|
20
|
-
|
21
|
-
|
22
|
-
Wrap an entire script
|
23
|
-
---------------------
|
24
|
-
|
25
|
-
Use the launcher script:
|
7
|
+
First `gem install pry-rescue pry-stack_explorer`. Then run your program with `rescue`
|
8
|
+
instead of `ruby`:
|
26
9
|
|
27
10
|
```
|
28
11
|
rescue <script.rb> [arguments..]
|
29
12
|
```
|
30
13
|
|
31
|
-
|
32
|
-
|
33
|
-
In development, wrap your code in `Pry::rescue{ }`; then any exceptions that are raised
|
34
|
-
but not rescued will open a pry session. This is particularly useful for debugging
|
35
|
-
servers and other long-running processes.
|
14
|
+
If you want more fine-grained control over which parts of your code are rescued, you can
|
15
|
+
also use the block form:
|
36
16
|
|
37
17
|
```ruby
|
38
18
|
require 'pry-rescue'
|
@@ -47,7 +27,6 @@ Pry.rescue do
|
|
47
27
|
test
|
48
28
|
end
|
49
29
|
```
|
50
|
-
|
51
30
|
This will land you in a pry-session:
|
52
31
|
|
53
32
|
```
|
@@ -119,9 +98,8 @@ you can get a better idea of why your function ended up in a bad state. Run
|
|
119
98
|
Known bugs
|
120
99
|
==========
|
121
100
|
|
122
|
-
Occasionally, when using ruby-1.8
|
123
|
-
|
124
|
-
expect.
|
101
|
+
Occasionally, when using ruby-1.8 the value for `self` will be incorrect. You will still
|
102
|
+
be able to access local variables, but calling methods will not work as you expect.
|
125
103
|
|
126
104
|
On rbx we are unable to intercept some exceptions thrown from inside the C++ VM, for
|
127
105
|
example the ZeroDivisionError in `1 / 0`.
|
data/lib/pry-rescue/commands.rb
CHANGED
@@ -31,7 +31,7 @@ Pry::Commands.create_command "cd-cause", "Move to the previously raised exceptio
|
|
31
31
|
BANNER
|
32
32
|
|
33
33
|
def process
|
34
|
-
raised = target.eval("_raised_ rescue nil")
|
34
|
+
raised = target.eval("_raised_.dup rescue nil")
|
35
35
|
raise Pry::CommandError, "cd-cause only works in a pry session created by Pry::rescue{}" unless raised
|
36
36
|
raised.pop
|
37
37
|
|
@@ -60,6 +60,6 @@ Pry::Commands.create_command "try-again", "Re-try the code that caused this exce
|
|
60
60
|
BANNER
|
61
61
|
|
62
62
|
def process
|
63
|
-
|
63
|
+
throw :try_again
|
64
64
|
end
|
65
65
|
end
|
data/lib/pry-rescue/core_ext.rb
CHANGED
@@ -10,21 +10,47 @@ class Pry
|
|
10
10
|
# @return [Object] The return value of the block
|
11
11
|
def self.rescue(&block)
|
12
12
|
raised = []
|
13
|
+
(@raised_stack ||= []) << raised
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
raised
|
17
|
-
|
18
|
-
|
15
|
+
loop do
|
16
|
+
catch(:try_again) do
|
17
|
+
raised.clear
|
18
|
+
begin
|
19
|
+
return Interception.listen(block) do |exception, binding|
|
20
|
+
if defined?(PryStackExplorer)
|
21
|
+
raised << [exception, binding.callers]
|
22
|
+
else
|
23
|
+
raised << [exception, Array(binding)]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
rescue Exception => e
|
27
|
+
PryRescue.enter_exception_context(raised)
|
28
|
+
raise e
|
29
|
+
end
|
19
30
|
end
|
20
31
|
end
|
32
|
+
ensure
|
33
|
+
@raised_stack.pop
|
34
|
+
end
|
21
35
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
36
|
+
# Start a pry session on an exception that you rescued within a Pry::rescue{ }.
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# Pry::rescue do
|
40
|
+
# begin
|
41
|
+
# raise "foo"
|
42
|
+
# rescue => e
|
43
|
+
# Pry::rescued(e)
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
def self.rescued(e=$!)
|
48
|
+
raise "Tried to inspect rescued exception outside Pry::rescue{ } block" unless @raised_stack.any?
|
49
|
+
|
50
|
+
raised = @raised_stack.last.dup
|
51
|
+
raised.pop until raised.empty? || raised.last.first == e
|
52
|
+
raise "Tried to inspect an exception that was not raised in this Pry::rescue{ } block" unless raised.any?
|
53
|
+
|
54
|
+
PryRescue.enter_exception_context(raised)
|
29
55
|
end
|
30
56
|
end
|
data/lib/pry-rescue.rb
CHANGED
@@ -17,10 +17,16 @@ class PryRescue
|
|
17
17
|
# @param [Exception] exception The exception.
|
18
18
|
# @param [Array<Binding>] bindings The call stack.
|
19
19
|
def enter_exception_context(raised)
|
20
|
-
exception, bindings = raised.last
|
21
20
|
|
21
|
+
exception, bindings = raised.last
|
22
22
|
prune_call_stack!(bindings)
|
23
23
|
|
24
|
+
if bindings.size > 1 && internal_binding?(bindings.first)
|
25
|
+
raised.pop
|
26
|
+
exception, bindings = raised.last
|
27
|
+
prune_call_stack!(bindings)
|
28
|
+
end
|
29
|
+
|
24
30
|
if defined?(PryStackExplorer)
|
25
31
|
pry :call_stack => bindings, :hooks => pry_hooks(exception, raised)
|
26
32
|
else
|
@@ -30,6 +36,12 @@ class PryRescue
|
|
30
36
|
|
31
37
|
private
|
32
38
|
|
39
|
+
# Is this binding within pry-rescue?
|
40
|
+
def internal_binding?(binding)
|
41
|
+
binding.eval("__FILE__").start_with?(File.expand_path('../../lib', __FILE__)) ||
|
42
|
+
binding.eval("__FILE__").start_with?(File.expand_path('../../bin', __FILE__))
|
43
|
+
end
|
44
|
+
|
33
45
|
# Define the :before_session hook for the Pry instance.
|
34
46
|
# This ensures that the `_ex_` and `_raised_` sticky locals are
|
35
47
|
# properly set.
|
data/pry-rescue.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'pry-rescue'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.4'
|
4
4
|
s.summary = 'Open a pry session on any unhandled exceptions'
|
5
5
|
s.description = 'Allows you to wrap code in Pry::rescue{ } to open a pry session at any unhandled exceptions'
|
6
6
|
s.homepage = 'https://github.com/ConradIrwin/pry-rescue'
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.expand_path('../../lib/pry-rescue.rb', __FILE__)
|
2
|
+
|
3
|
+
describe 'Pry.rescue' do
|
4
|
+
it 'should call PryRescue.enter_exception_context' do
|
5
|
+
lambda{
|
6
|
+
PryRescue.should_receive(:enter_exception_context).once
|
7
|
+
Pry::rescue{ raise "foobar" }
|
8
|
+
}.should raise_error(/foobar/)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should retry on try-again" do
|
12
|
+
@called = 0
|
13
|
+
PryRescue.should_receive(:enter_exception_context).once{ throw :try_again }
|
14
|
+
Pry::rescue do
|
15
|
+
@called += 1
|
16
|
+
raise "foobar" if @called == 1
|
17
|
+
end
|
18
|
+
@called.should == 2
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should try-again from innermost block" do
|
22
|
+
@outer = @inner = 0
|
23
|
+
PryRescue.should_receive(:enter_exception_context).once{ throw :try_again }
|
24
|
+
Pry::rescue do
|
25
|
+
@outer += 1
|
26
|
+
Pry::rescue do
|
27
|
+
@inner += 1
|
28
|
+
raise "oops" if @inner == 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
@outer.should == 1
|
33
|
+
@inner.should == 2
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should clear out exceptions between retrys at the same level" do
|
37
|
+
@outer = @inner = 0
|
38
|
+
PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
|
39
|
+
PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
|
40
|
+
Pry::rescue do
|
41
|
+
@outer += 1
|
42
|
+
Pry::rescue do
|
43
|
+
@inner += 1
|
44
|
+
raise "oops" if @inner <= 2
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should preserve exceptions between retrys at a higher level" do
|
50
|
+
@outer = @inner = 0
|
51
|
+
PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
|
52
|
+
PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
|
53
|
+
PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 3; throw :try_again }
|
54
|
+
Pry::rescue do
|
55
|
+
@outer += 1
|
56
|
+
Pry::rescue do
|
57
|
+
@inner += 1
|
58
|
+
raise "oops" if @inner <= 2
|
59
|
+
end
|
60
|
+
raise "foops" if @outer == 1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "Pry.rescued" do
|
66
|
+
|
67
|
+
it "should raise an error if used outwith Pry::rescue" do
|
68
|
+
begin
|
69
|
+
raise "foo"
|
70
|
+
rescue => e
|
71
|
+
lambda{
|
72
|
+
Pry.rescued(e)
|
73
|
+
}.should raise_error(/outside Pry::rescue/)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should raise an error if used on an exception not raised" do
|
78
|
+
Pry::rescue do
|
79
|
+
lambda{
|
80
|
+
Pry.rescued(RuntimeError.new("foo").exception)
|
81
|
+
}.should raise_error(/not raised/)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should call Pry.enter_exception_context" do
|
86
|
+
Pry::rescue do
|
87
|
+
begin
|
88
|
+
raise "foo"
|
89
|
+
rescue => e
|
90
|
+
PryRescue.should_receive(:enter_exception_context).once
|
91
|
+
Pry::rescued(e)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pry-rescue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.4'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-08-
|
14
|
+
date: 2012-08-26 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: interception
|
@@ -51,6 +51,7 @@ files:
|
|
51
51
|
- lib/pry-rescue/commands.rb
|
52
52
|
- lib/pry-rescue/core_ext.rb
|
53
53
|
- pry-rescue.gemspec
|
54
|
+
- spec/core_ext_spec.rb
|
54
55
|
homepage: https://github.com/ConradIrwin/pry-rescue
|
55
56
|
licenses: []
|
56
57
|
post_install_message:
|