pry-rescue 0.8 → 0.9.pre.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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- **pry-rescue** super-fast, painless, debugging for the (ruby) masses. (See [Pry to the rescue!](https://cirw.in/blog/pry-to-the-rescue))
2
+ **pry-rescue** super-fast, painless, debugging for the (ruby) masses. (See [Pry to the rescue!](http://cirw.in/blog/pry-to-the-rescue))
3
3
 
4
4
  Usage
5
5
  =====
data/lib/pry-rescue.rb CHANGED
@@ -24,11 +24,12 @@ class PryRescue
24
24
  # Start a Pry session in the context of the exception.
25
25
  # @param [Array<Exception, Array<Binding>>] raised The exceptions raised
26
26
  def enter_exception_context(raised)
27
+ @exception_context_depth ||= 0
28
+ @exception_context_depth += 1
27
29
 
28
30
  raised = raised.map do |e, bs|
29
31
  [e, without_bindings_below_raise(bs)]
30
32
  end
31
- raised = without_gem_reraises(raised)
32
33
 
33
34
  raised.pop if phantom_load_raise?(*raised.last)
34
35
  exception, bindings = raised.last
@@ -41,6 +42,8 @@ class PryRescue
41
42
  else
42
43
  Pry.start bindings.first, :hooks => pry_hooks(exception, raised)
43
44
  end
45
+ ensure
46
+ @exception_context_depth -= 1
44
47
  end
45
48
 
46
49
  # Load a script wrapped in Pry::rescue{ }
@@ -49,6 +52,12 @@ class PryRescue
49
52
  Pry::rescue{ Kernel.load script }
50
53
  end
51
54
 
55
+ # Is the user currently inside pry rescue?
56
+ # @return [Boolean]
57
+ def in_exception_context?
58
+ @exception_context_depth && @exception_context_depth > 0
59
+ end
60
+
52
61
  private
53
62
 
54
63
  # Did this raise happen within pry-rescue?
@@ -81,7 +90,8 @@ class PryRescue
81
90
  # @return [Boolean]
82
91
  def user_path?(file)
83
92
  !file.start_with?(RbConfig::CONFIG['libdir']) &&
84
- !Gem::Specification.any?{ |gem| file.start_with?(gem.full_gem_path) }
93
+ !Gem::Specification.any?{ |gem| file.start_with?(gem.full_gem_path) } &&
94
+ !(file == '<internal:prelude>')
85
95
  end
86
96
 
87
97
  # Remove bindings that are part of Interception/Pry.rescue's internal
@@ -105,28 +115,11 @@ class PryRescue
105
115
  bindings.zip([nil] + bindings).reject do |b, c|
106
116
  # The eval('__method__') is there as a shortcut as loading a method
107
117
  # from a binding is very slow.
108
- c && (b.eval("__method__") == c.eval("__method__")) &&
118
+ c && (b.eval("::Kernel.__method__") == c.eval("::Kernel.__method__")) &&
109
119
  Pry::Method.from_binding(b) == Pry::Method.from_binding(c)
110
120
  end.map(&:first)
111
121
  end
112
122
 
113
- # Remove any re-raises of the exact exception object that happened from within
114
- # a gem, and show you only the raise that happened in your code.
115
- #
116
- # @param [Array<Exception, Array<Binding>>] raised The exceptions raised
117
- def without_gem_reraises(raised)
118
- seen = {}
119
- raised.select do |(e, bindings)|
120
- if seen[e] && !user_path?(bindings.first.eval("__FILE__"))
121
- false
122
- elsif user_path?(bindings.first.eval("__FILE__"))
123
- seen[e] = true
124
- else
125
- true
126
- end
127
- end
128
- end
129
-
130
123
  # Define the :before_session hook for the Pry instance.
131
124
  # This ensures that the `_ex_` and `_raised_` sticky locals are
132
125
  # properly set.
@@ -12,15 +12,15 @@ Pry::Commands.create_command "cd-cause", "Move to the previously raised exceptio
12
12
  5. def foo
13
13
  6. raise "one"
14
14
  7. rescue
15
- 8. => raise "two"
15
+ 8. => raise "two"
16
16
  9. end
17
17
 
18
18
  pry> cd-cause
19
19
 
20
20
  5. def foo
21
- 6. => raise "one"
21
+ 6. => raise "one"
22
22
  7. rescue
23
- 8. raise "two"
23
+ 8. raise "two"
24
24
  9. end
25
25
 
26
26
  Once you have finished with the internal exception type <ctrl+d> or cd .. to
@@ -60,6 +60,7 @@ Pry::Commands.create_command "try-again", "Re-try the code that caused this exce
60
60
  BANNER
61
61
 
62
62
  def process
63
+ raise Pry::CommandError, "try-again only works in a pry session created by Pry::rescue{}" unless PryRescue.in_exception_context?
63
64
  throw :try_again
64
65
  end
65
66
  end
@@ -1,5 +1,5 @@
1
1
  # Additional methods provided by pry-rescue.
2
- class Pry
2
+ class << Pry
3
3
  # Start a pry session on any unhandled exceptions within this block.
4
4
  #
5
5
  # @example
@@ -8,29 +8,18 @@ class Pry
8
8
  # end
9
9
  #
10
10
  # @return [Object] The return value of the block
11
- def self.rescue(&block)
12
- raised = []
13
- (@raised_stack ||= []) << raised
14
-
11
+ def rescue(&block)
15
12
  loop do
16
13
  catch(:try_again) do
17
- raised.clear
14
+ @raised = []
18
15
  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
16
+ return with_rescuing(&block)
26
17
  rescue Exception => e
27
- PryRescue.enter_exception_context(raised)
18
+ rescued e
28
19
  raise e
29
20
  end
30
21
  end
31
22
  end
32
- ensure
33
- @raised_stack.pop
34
23
  end
35
24
 
36
25
  # Start a pry session on an exception that you rescued within a Pry::rescue{ }.
@@ -44,13 +33,38 @@ class Pry
44
33
  # end
45
34
  # end
46
35
  #
47
- def self.rescued(e=$!)
48
- raise "Tried to inspect rescued exception outside Pry::rescue{ } block" unless @raised_stack.any?
36
+ def rescued(e=$!)
37
+ if i = (@raised || []).index{ |(ee, _)| ee == e }
38
+ PryRescue.enter_exception_context(@raised[0..i])
39
+ else
40
+ raise "Tried to inspect an exception that was not raised in a Pry::rescue{ } block"
41
+ end
42
+
43
+ ensure
44
+ @raised = []
45
+ end
49
46
 
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?
47
+ private
53
48
 
54
- PryRescue.enter_exception_context(raised)
49
+ # Ensure that Interception is active while running this block
50
+ #
51
+ # @param [Proc] &block the block
52
+ def with_rescuing(&block)
53
+ if @rescuing
54
+ block.call
55
+ else
56
+ begin
57
+ @rescuing = true
58
+ Interception.listen(block) do |exception, binding|
59
+ if defined?(PryStackExplorer)
60
+ @raised << [exception, binding.callers]
61
+ else
62
+ @raised << [exception, Array(binding)]
63
+ end
64
+ end
65
+ ensure
66
+ @rescuing = false
67
+ end
68
+ end
55
69
  end
56
70
  end
@@ -0,0 +1,33 @@
1
+ require 'pry-rescue'
2
+ class PryRescue
3
+ class Railtie < ::Rails::Railtie
4
+
5
+ initializer "pry_rescue" do |app|
6
+ if Rails.env.development?
7
+ app.config.middleware.use PryRescue::Rack
8
+
9
+ if defined?(::ActionDispatch::DebugExceptions)
10
+ monkeypatch(::ActionDispatch::DebugExceptions)
11
+
12
+ elsif defined?(::ActionDispatch::ShowExceptions)
13
+ monkeypatch(::ActionDispatch::ShowExceptions)
14
+
15
+ else
16
+ raise LoadError, "Sorry, your version of rails is not supported."
17
+ end
18
+ end
19
+ end
20
+
21
+ def monkeypatch(middleware)
22
+ middleware.class_eval do
23
+
24
+ def render_exception_with_pry_rescue(env, exception)
25
+ Pry::rescued(exception)
26
+ render_exception_without_pry_rescue(env, exception)
27
+ end
28
+
29
+ alias_method_chain :render_exception, :pry_rescue
30
+ end
31
+ end
32
+ end
33
+ end
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.8'
3
+ s.version = '0.9.pre.1'
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,60 @@
1
+ describe "pry-rescue commands" do
2
+ describe "try-again" do
3
+ it "should throw try_again" do
4
+ PryRescue.should_receive(:in_exception_context?).and_return{ true }
5
+
6
+ lambda{
7
+ Pry.new.process_command "try-again", '', TOPLEVEL_BINDING
8
+ }.should throw_symbol :try_again
9
+ end
10
+
11
+ it "should raise a CommandError if not in Pry::rescue" do
12
+ PryRescue.should_receive(:in_exception_context?).and_return{ false }
13
+
14
+ lambda{
15
+ Pry.new.process_command "try-again", '', TOPLEVEL_BINDING
16
+ }.should raise_error Pry::CommandError
17
+ end
18
+ end
19
+
20
+ describe "cd-cause" do
21
+ it "should enter the next exception's context" do
22
+ begin
23
+ begin
24
+ b1 = binding
25
+ raise "original"
26
+ rescue => e1
27
+ b2 = binding
28
+ raise
29
+ end
30
+ rescue => e2
31
+ _raised_ = [[e1, [b1]], [e2, [b2]]]
32
+ end
33
+
34
+ PryRescue.should_receive(:enter_exception_context).once.with{ |raised|
35
+ raised.should == [[e1, [b1]]]
36
+ }
37
+
38
+ Pry.new.process_command 'cd-cause', '', binding
39
+ end
40
+
41
+ it "should raise a CommandError if no previous commands" do
42
+ begin
43
+ b1 = binding
44
+ raise "original"
45
+ rescue => e1
46
+ _raised_ = [[e1, [b1]]]
47
+ end
48
+
49
+ lambda{
50
+ Pry.new.process_command 'cd-cause', '', binding
51
+ }.should raise_error Pry::CommandError, /No previous exception/
52
+ end
53
+
54
+ it "should raise a CommandError if not in Pry::rescue" do
55
+ lambda{
56
+ Pry.new.process_command 'cd-cause', '', binding
57
+ }.should raise_error Pry::CommandError, /Pry::rescue/
58
+ end
59
+ end
60
+ end
@@ -46,11 +46,11 @@ describe 'Pry.rescue' do
46
46
  end
47
47
  end
48
48
 
49
- it "should preserve exceptions between retrys at a higher level" do
49
+ it "should clear out exceptions between retrys at a higher level" do
50
50
  @outer = @inner = 0
51
51
  PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
52
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 }
53
+ PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
54
54
  Pry::rescue do
55
55
  @outer += 1
56
56
  Pry::rescue do
@@ -60,6 +60,19 @@ describe 'Pry.rescue' do
60
60
  raise "foops" if @outer == 1
61
61
  end
62
62
  end
63
+
64
+ it "should enter the first occurence of an exception that is re-raised" do
65
+ PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1 }
66
+ lambda do
67
+ Pry::rescue do
68
+ begin
69
+ raise "first_occurance"
70
+ rescue => e
71
+ raise
72
+ end
73
+ end
74
+ end.should raise_error /first_occurance/
75
+ end
63
76
  end
64
77
 
65
78
  describe "Pry.rescued" do
@@ -70,7 +83,7 @@ describe "Pry.rescued" do
70
83
  rescue => e
71
84
  lambda{
72
85
  Pry.rescued(e)
73
- }.should raise_error(/outside Pry::rescue/)
86
+ }.should raise_error(/Pry::rescue/)
74
87
  end
75
88
  end
76
89
 
metadata CHANGED
@@ -1,109 +1,97 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: pry-rescue
3
- version: !ruby/object:Gem::Version
4
- version: '0.8'
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: true
5
+ segments:
6
+ - 0
7
+ - 9
8
+ - pre
9
+ - 1
10
+ version: 0.9.pre.1
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Conrad Irwin
9
14
  - banisterfiend
10
15
  - epitron
11
16
  autorequire:
12
17
  bindir: bin
13
18
  cert_chain: []
14
- date: 2012-08-31 00:00:00.000000000 Z
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
19
+
20
+ date: 2012-09-30 00:00:00 -07:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
17
24
  name: pry
18
- requirement: !ruby/object:Gem::Requirement
19
- none: false
20
- requirements:
21
- - - ! '>='
22
- - !ruby/object:Gem::Version
23
- version: '0'
24
- type: :runtime
25
25
  prerelease: false
26
- version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
- requirements:
29
- - - ! '>='
30
- - !ruby/object:Gem::Version
31
- version: '0'
32
- - !ruby/object:Gem::Dependency
33
- name: interception
34
- requirement: !ruby/object:Gem::Requirement
35
- none: false
36
- requirements:
37
- - - ! '>='
38
- - !ruby/object:Gem::Version
39
- version: '0'
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ segments:
31
+ - 0
32
+ version: "0"
40
33
  type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: interception
41
37
  prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- none: false
44
- requirements:
45
- - - ! '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- - !ruby/object:Gem::Dependency
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :runtime
46
+ version_requirements: *id002
47
+ - !ruby/object:Gem::Dependency
49
48
  name: rspec
50
- requirement: !ruby/object:Gem::Requirement
51
- none: false
52
- requirements:
53
- - - ! '>='
54
- - !ruby/object:Gem::Version
55
- version: '0'
56
- type: :development
57
49
  prerelease: false
58
- version_requirements: !ruby/object:Gem::Requirement
59
- none: false
60
- requirements:
61
- - - ! '>='
62
- - !ruby/object:Gem::Version
63
- version: '0'
64
- - !ruby/object:Gem::Dependency
65
- name: yard
66
- requirement: !ruby/object:Gem::Requirement
67
- none: false
68
- requirements:
69
- - - ! '>='
70
- - !ruby/object:Gem::Version
71
- version: '0'
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
72
57
  type: :development
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: yard
73
61
  prerelease: false
74
- version_requirements: !ruby/object:Gem::Requirement
75
- none: false
76
- requirements:
77
- - - ! '>='
78
- - !ruby/object:Gem::Version
79
- version: '0'
80
- - !ruby/object:Gem::Dependency
81
- name: redcarpet
82
- requirement: !ruby/object:Gem::Requirement
83
- none: false
84
- requirements:
85
- - - ! '>='
86
- - !ruby/object:Gem::Version
87
- version: '0'
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
88
69
  type: :development
70
+ version_requirements: *id004
71
+ - !ruby/object:Gem::Dependency
72
+ name: redcarpet
89
73
  prerelease: false
90
- version_requirements: !ruby/object:Gem::Requirement
91
- none: false
92
- requirements:
93
- - - ! '>='
94
- - !ruby/object:Gem::Version
95
- version: '0'
96
- description: Allows you to wrap code in Pry::rescue{ } to open a pry session at any
97
- unhandled exceptions
98
- email:
74
+ requirement: &id005 !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ type: :development
82
+ version_requirements: *id005
83
+ description: Allows you to wrap code in Pry::rescue{ } to open a pry session at any unhandled exceptions
84
+ email:
99
85
  - conrad.irwin@gmail.com
100
86
  - jrmair@gmail.com
101
87
  - chris@ill-logic.com
102
- executables:
88
+ executables:
103
89
  - rescue
104
90
  extensions: []
91
+
105
92
  extra_rdoc_files: []
106
- files:
93
+
94
+ files:
107
95
  - .gitignore
108
96
  - Gemfile
109
97
  - LICENSE.MIT
@@ -118,8 +106,10 @@ files:
118
106
  - lib/pry-rescue/commands.rb
119
107
  - lib/pry-rescue/core_ext.rb
120
108
  - lib/pry-rescue/rack.rb
109
+ - lib/pry-rescue/rails.rb
121
110
  - lib/pry/rescue.rb
122
111
  - pry-rescue.gemspec
112
+ - spec/commands_spec.rb
123
113
  - spec/core_ext_spec.rb
124
114
  - spec/fixtures/coderay.rb
125
115
  - spec/fixtures/initial.rb
@@ -129,29 +119,37 @@ files:
129
119
  - spec/fixtures/super.rb
130
120
  - spec/fixtures/uri.rb
131
121
  - spec/pry_rescue_spec.rb
122
+ has_rdoc: true
132
123
  homepage: https://github.com/ConradIrwin/pry-rescue
133
124
  licenses: []
125
+
134
126
  post_install_message:
135
127
  rdoc_options: []
136
- require_paths:
128
+
129
+ require_paths:
137
130
  - lib
138
- required_ruby_version: !ruby/object:Gem::Requirement
139
- none: false
140
- requirements:
141
- - - ! '>='
142
- - !ruby/object:Gem::Version
143
- version: '0'
144
- required_rubygems_version: !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ! '>='
148
- - !ruby/object:Gem::Version
149
- version: '0'
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ segments:
136
+ - 0
137
+ version: "0"
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">"
141
+ - !ruby/object:Gem::Version
142
+ segments:
143
+ - 1
144
+ - 3
145
+ - 1
146
+ version: 1.3.1
150
147
  requirements: []
148
+
151
149
  rubyforge_project:
152
- rubygems_version: 1.8.23
150
+ rubygems_version: 1.3.6
153
151
  signing_key:
154
152
  specification_version: 3
155
153
  summary: Open a pry session on any unhandled exceptions
156
154
  test_files: []
157
- has_rdoc:
155
+