pry-rescue 0.7 → 0.8

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