pry-rescue 0.7 → 0.8

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 ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ Gemfile.lock
3
+ .rbx
4
+ .yardoc
5
+ doc
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/README.md CHANGED
@@ -11,6 +11,12 @@ instead of `ruby`:
11
11
  rescue <script.rb> [arguments..]
12
12
  ```
13
13
 
14
+ If you're using Rack, you should use the middleware instead (though be careful to only
15
+ include it in development!)
16
+ ```
17
+ use PryRescue::Rack
18
+ ```
19
+
14
20
  If you want more fine-grained control over which parts of your code are rescued, you can
15
21
  also use the block form:
16
22
 
data/lib/pry-rescue.rb CHANGED
@@ -4,29 +4,38 @@ require 'pry'
4
4
 
5
5
  require File.expand_path('../pry-rescue/core_ext', __FILE__)
6
6
  require File.expand_path('../pry-rescue/commands', __FILE__)
7
+ require File.expand_path('../pry-rescue/rack', __FILE__)
7
8
 
8
9
  begin
9
10
  require 'pry-stack_explorer'
10
11
  rescue LoadError
11
12
  end
12
13
 
14
+ # PryRescue provides the ability to open a Pry shell whenever an unhandled exception is
15
+ # raised in your code.
16
+ #
17
+ # The main API is exposed via the Pry object, but here are a load of helpers that I didn't
18
+ # want to pollute the Pry namespace with.
19
+ #
20
+ # @see {Pry::rescue}
13
21
  class PryRescue
14
22
  class << self
15
23
 
16
24
  # Start a Pry session in the context of the exception.
17
- # @param [Exception] exception The exception.
18
- # @param [Array<Binding>] bindings The call stack.
25
+ # @param [Array<Exception, Array<Binding>>] raised The exceptions raised
19
26
  def enter_exception_context(raised)
20
27
 
21
28
  raised = raised.map do |e, bs|
22
29
  [e, without_bindings_below_raise(bs)]
23
30
  end
31
+ raised = without_gem_reraises(raised)
24
32
 
25
33
  raised.pop if phantom_load_raise?(*raised.last)
26
34
  exception, bindings = raised.last
35
+ bindings = without_duplicates(bindings)
27
36
 
28
37
  if defined?(PryStackExplorer)
29
- pry :call_stack => without_duplicates(bindings),
38
+ pry :call_stack => bindings,
30
39
  :hooks => pry_hooks(exception, raised),
31
40
  :initial_frame => initial_frame(bindings)
32
41
  else
@@ -35,7 +44,7 @@ class PryRescue
35
44
  end
36
45
 
37
46
  # Load a script wrapped in Pry::rescue{ }
38
- # @param [String] The name of the script
47
+ # @param [String] script The name of the script
39
48
  def load(script)
40
49
  Pry::rescue{ Kernel.load script }
41
50
  end
@@ -46,7 +55,9 @@ class PryRescue
46
55
  #
47
56
  # This is designed to remove the extra raise that is caused by PryRescue.load.
48
57
  # TODO: we should figure out why it happens...
49
- # @param [Array<Binding>]
58
+ #
59
+ # @param [Exception] e The raised exception
60
+ # @param [Array<Binding>] bindings The call stack
50
61
  def phantom_load_raise?(e, bindings)
51
62
  bindings.any? && bindings.first.eval("__FILE__") == __FILE__
52
63
  end
@@ -54,7 +65,7 @@ class PryRescue
54
65
  # When using pry-stack-explorer we want to start the rescue session outside of gems
55
66
  # and the standard library, as that is most helpful for users.
56
67
  #
57
- # @param [Array<Bindings>] All bindings
68
+ # @param [Array<Bindings>] bindings All bindings
58
69
  # @return [Fixnum] The offset of the first binding of user code
59
70
  def initial_frame(bindings)
60
71
  bindings.each_with_index do |binding, i|
@@ -66,7 +77,7 @@ class PryRescue
66
77
 
67
78
  # Is this path likely to be code the user is working with right now?
68
79
  #
69
- # @param [String] the absolute path
80
+ # @param [String] file the absolute path
70
81
  # @return [Boolean]
71
82
  def user_path?(file)
72
83
  !file.start_with?(RbConfig::CONFIG['libdir']) &&
@@ -76,7 +87,7 @@ class PryRescue
76
87
  # Remove bindings that are part of Interception/Pry.rescue's internal
77
88
  # event handling that happens as part of the exception hooking process.
78
89
  #
79
- # @param [Array<Binding>] bindings The call stack.
90
+ # @param [Array<Binding>] bindings The call stack.
80
91
  def without_bindings_below_raise(bindings)
81
92
  return bindings if bindings.size <= 1
82
93
  bindings.drop_while do |b|
@@ -88,7 +99,7 @@ class PryRescue
88
99
 
89
100
  # Remove multiple bindings for the same function.
90
101
  #
91
- # @param [Array<Bindings>]
102
+ # @param [Array<Bindings>] bindings The call stack
92
103
  # @return [Array<Bindings>]
93
104
  def without_duplicates(bindings)
94
105
  bindings.zip([nil] + bindings).reject do |b, c|
@@ -99,9 +110,29 @@ class PryRescue
99
110
  end.map(&:first)
100
111
  end
101
112
 
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
+
102
130
  # Define the :before_session hook for the Pry instance.
103
131
  # This ensures that the `_ex_` and `_raised_` sticky locals are
104
132
  # properly set.
133
+ #
134
+ # @param [Exception] ex The exception we're currently looking at
135
+ # @param [Array<Exception, Array<Binding>>] raised The exceptions raised
105
136
  def pry_hooks(ex, raised)
106
137
  hooks = Pry.config.hooks.dup
107
138
  hooks.add_hook(:before_session, :save_captured_exception) do |_, _, _pry_|
@@ -1,5 +1,5 @@
1
+ # Additional methods provided by pry-rescue.
1
2
  class Pry
2
-
3
3
  # Start a pry session on any unhandled exceptions within this block.
4
4
  #
5
5
  # @example
@@ -0,0 +1,19 @@
1
+ require 'pry-rescue'
2
+
3
+ class PryRescue
4
+ # A Rack middleware that wraps each web request in Pry::rescue.
5
+ class Rack
6
+ # Instantiate the middleware
7
+ #
8
+ # @param [#call] app
9
+ def initialize(app)
10
+ @app = app
11
+ end
12
+
13
+ # Handle a web request
14
+ # @param [Rack::Env] env
15
+ def call(env)
16
+ Pry::rescue{ @app.call(env) }
17
+ end
18
+ end
19
+ 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.7'
3
+ s.version = '0.8'
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'
@@ -12,4 +12,8 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.add_dependency 'pry'
14
14
  s.add_dependency 'interception'
15
+
16
+ s.add_development_dependency 'rspec'
17
+ s.add_development_dependency 'yard'
18
+ s.add_development_dependency 'redcarpet'
15
19
  end
@@ -0,0 +1,13 @@
1
+ eval <<EOF, TOPLEVEL_BINDING, File.join(RbConfig::CONFIG['rubylibdir'], 'fake.rb'), 1
2
+
3
+ module Test
4
+ def self.foo(*args)
5
+ args.each do |a|
6
+ raise ArgumentError, "no :baz please" if a == :baz
7
+ end
8
+ end
9
+ end
10
+
11
+ EOF
12
+
13
+ Test.foo(:baz)
@@ -0,0 +1,13 @@
1
+ eval <<EOF, TOPLEVEL_BINDING, File.join(RbConfig::CONFIG['rubylibdir'], 'fake.rb'), 1
2
+
3
+ module Test
4
+ def self.baz(*args)
5
+ yield
6
+ rescue => e
7
+ raiseother_exception
8
+ end
9
+ end
10
+
11
+ EOF
12
+
13
+ Test.baz{ raise "reraise-exception" }
@@ -0,0 +1,13 @@
1
+ eval <<EOF, TOPLEVEL_BINDING, File.join(RbConfig::CONFIG['rubylibdir'], 'fake.rb'), 1
2
+
3
+ module Test
4
+ def self.bar(*args)
5
+ yield
6
+ rescue => e
7
+ raise e
8
+ end
9
+ end
10
+
11
+ EOF
12
+
13
+ Test.bar{ raise "reraise-exception" }
@@ -1 +1 @@
1
- raise "fixtures/simple"
1
+ raise "simple-exception"
@@ -0,0 +1,17 @@
1
+ class A
2
+ def a
3
+ loop do
4
+ raise "super-exception"
5
+ end
6
+ end
7
+ end
8
+
9
+ class B < A
10
+ def a
11
+ loop do
12
+ super
13
+ end
14
+ end
15
+ end
16
+
17
+ B.new.a
@@ -9,7 +9,7 @@ describe "PryRescue.load" do
9
9
  }
10
10
  lambda{
11
11
  PryRescue.load("spec/fixtures/simple.rb")
12
- }.should raise_error(/fixtures.simple/)
12
+ }.should raise_error(/simple-exception/)
13
13
  end
14
14
 
15
15
  it "should open above the standard library" do
@@ -55,7 +55,35 @@ describe "PryRescue.load" do
55
55
  end
56
56
  lambda{
57
57
  PryRescue.load("spec/fixtures/super.rb")
58
- }.should raise_error(/fixtures.super/)
58
+ }.should raise_error(/super-exception/)
59
+ end
60
+
61
+ it "should calculate correct initial frame even when duplicates are present" do
62
+ PryRescue.should_receive(:pry).once do |opts|
63
+ opts[:call_stack][0].eval("__FILE__").should end_with('fake.rb')
64
+ opts[:call_stack][opts[:initial_frame]].eval("__FILE__").should end_with('spec/fixtures/initial.rb')
65
+ end
66
+ lambda{
67
+ PryRescue.load("spec/fixtures/initial.rb")
68
+ }.should raise_error(/no :baz please/)
69
+ end
70
+
71
+ it "should skip over reraises from within gems" do
72
+ PryRescue.should_receive(:pry).once do |opts|
73
+ opts[:call_stack][0].eval("__FILE__").should end_with('spec/fixtures/reraise.rb')
74
+ end
75
+ lambda{
76
+ PryRescue.load("spec/fixtures/reraise.rb")
77
+ }.should raise_error(/reraise-exception/)
78
+ end
79
+
80
+ it "should not skip over independent raises within gems" do
81
+ PryRescue.should_receive(:pry).once do |opts|
82
+ opts[:call_stack][0].eval("__FILE__").should end_with('fake.rb')
83
+ end
84
+ lambda{
85
+ PryRescue.load("spec/fixtures/raiseother.rb")
86
+ }.should raise_error(/raiseother_exception/)
59
87
  end
60
88
  else
61
89
  it "should open at the correct point" do
@@ -64,7 +92,7 @@ describe "PryRescue.load" do
64
92
  }
65
93
  lambda{
66
94
  PryRescue.load("spec/fixtures/simple.rb")
67
- }.should raise_error(/fixtures.simple/)
95
+ }.should raise_error(/simple-exception/)
68
96
  end
69
97
  end
70
98
  end
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.7'
4
+ version: '0.8'
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-28 00:00:00.000000000 Z
14
+ date: 2012-08-31 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: pry
@@ -45,6 +45,54 @@ dependencies:
45
45
  - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ 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
+ 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'
72
+ type: :development
73
+ 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'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
48
96
  description: Allows you to wrap code in Pry::rescue{ } to open a pry session at any
49
97
  unhandled exceptions
50
98
  email:
@@ -56,6 +104,8 @@ executables:
56
104
  extensions: []
57
105
  extra_rdoc_files: []
58
106
  files:
107
+ - .gitignore
108
+ - Gemfile
59
109
  - LICENSE.MIT
60
110
  - README.md
61
111
  - Rakefile
@@ -67,11 +117,16 @@ files:
67
117
  - lib/pry-rescue/cli.rb
68
118
  - lib/pry-rescue/commands.rb
69
119
  - lib/pry-rescue/core_ext.rb
120
+ - lib/pry-rescue/rack.rb
70
121
  - lib/pry/rescue.rb
71
122
  - pry-rescue.gemspec
72
123
  - spec/core_ext_spec.rb
73
124
  - spec/fixtures/coderay.rb
125
+ - spec/fixtures/initial.rb
126
+ - spec/fixtures/raiseother.rb
127
+ - spec/fixtures/reraise.rb
74
128
  - spec/fixtures/simple.rb
129
+ - spec/fixtures/super.rb
75
130
  - spec/fixtures/uri.rb
76
131
  - spec/pry_rescue_spec.rb
77
132
  homepage: https://github.com/ConradIrwin/pry-rescue
@@ -94,8 +149,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
149
  version: '0'
95
150
  requirements: []
96
151
  rubyforge_project:
97
- rubygems_version: 1.8.24
152
+ rubygems_version: 1.8.23
98
153
  signing_key:
99
154
  specification_version: 3
100
155
  summary: Open a pry session on any unhandled exceptions
101
156
  test_files: []
157
+ has_rdoc: