pry-exception_explorer 0.2.0pre4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +11 -1
- data/examples/example_c_inline.rb +6 -1
- data/examples/example_inline.rb +1 -1
- data/lib/pry-exception_explorer.rb +35 -16
- data/lib/pry-exception_explorer/commands.rb +1 -1
- data/lib/pry-exception_explorer/core_ext.rb +2 -3
- data/lib/pry-exception_explorer/version.rb +1 -1
- data/pry-exception_explorer.gemspec +3 -3
- data/test/test_inline_exceptions.rb +89 -56
- data/test/test_wrapped_exceptions.rb +1 -1
- metadata +11 -11
data/Rakefile
CHANGED
@@ -56,7 +56,17 @@ end
|
|
56
56
|
|
57
57
|
desc "Run example C inline"
|
58
58
|
task :example_c_inline do
|
59
|
-
sh "
|
59
|
+
sh "ruby -I#{direc}/lib/ #{direc}/examples/example_c_inline.rb "
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "Run example C wrap"
|
63
|
+
task :example_c_wrap do
|
64
|
+
sh "ruby -I#{direc}/lib/ #{direc}/examples/example_c_wrap.rb "
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "Run example post mortem"
|
68
|
+
task :example_post_mortem do
|
69
|
+
sh "ruby -I#{direc}/lib/ #{direc}/examples/example_post_mortem.rb "
|
60
70
|
end
|
61
71
|
|
62
72
|
task :default => :test
|
@@ -5,7 +5,12 @@ end
|
|
5
5
|
|
6
6
|
require 'pry-exception_explorer'
|
7
7
|
|
8
|
-
|
8
|
+
EE.inline!
|
9
|
+
|
10
|
+
# we need to fine tune intercept when intercepting C exceptions
|
11
|
+
# otherwise we could be intercepting exceptions internal to rubygems
|
12
|
+
# and god knows what else...
|
13
|
+
EE.intercept(ZeroDivisionError)
|
9
14
|
|
10
15
|
def alpha
|
11
16
|
name = "john"
|
data/examples/example_inline.rb
CHANGED
@@ -23,24 +23,37 @@ module PryExceptionExplorer
|
|
23
23
|
|
24
24
|
class << self
|
25
25
|
|
26
|
-
# @return [Hash] A local hash.
|
27
|
-
def local_hash
|
28
|
-
@hash ||= {}
|
29
|
-
end
|
30
|
-
|
31
26
|
# @return [Boolean] Whether exceptions are to be intercepted
|
32
27
|
# inline (at the raise site).
|
33
28
|
attr_accessor :inline
|
29
|
+
|
30
|
+
# @return [Boolean] Whether exceptions are to be auto-rescued
|
31
|
+
# if they would terminate the program.
|
34
32
|
attr_accessor :post_mortem
|
35
33
|
|
36
|
-
#
|
34
|
+
# @return [Boolean] Holds the previous value of `EE.inline`
|
35
|
+
attr_accessor :old_inline_state
|
36
|
+
|
37
|
+
# Ensure exceptions are intercepted at the raise site, and enable EE.
|
37
38
|
def inline!
|
39
|
+
self.enabled = true
|
38
40
|
self.inline = true
|
39
41
|
end
|
40
42
|
|
43
|
+
# Ensure exceptions are intercepted if they would terminate the program, and enable EE.
|
44
|
+
def post_mortem!
|
45
|
+
self.enabled = true
|
46
|
+
self.post_mortem = true
|
47
|
+
end
|
48
|
+
|
41
49
|
alias_method :inline?, :inline
|
42
50
|
alias_method :post_mortem?, :post_mortem
|
43
51
|
|
52
|
+
# @return [Hash] A local hash.
|
53
|
+
def local_hash
|
54
|
+
@hash ||= {}
|
55
|
+
end
|
56
|
+
|
44
57
|
# Enable Exception Explorer.
|
45
58
|
# @return [Boolean]
|
46
59
|
def enable!
|
@@ -193,25 +206,28 @@ module PryExceptionExplorer
|
|
193
206
|
# @option options [Boolean] :inline Whether the exception is being
|
194
207
|
# entered inline (i.e within the `raise` method itself)
|
195
208
|
def enter_exception(ex, options={})
|
196
|
-
hooks = Pry.config.hooks.dup
|
209
|
+
hooks = Pry.config.hooks.dup
|
210
|
+
hooks.delete_hook(:before_session, :default)
|
211
|
+
hooks.add_hook(:before_session, :set_exception_flag) do |_, _, _pry_|
|
197
212
|
setup_exception_context(ex, _pry_, options)
|
198
213
|
end.add_hook(:before_session, :manage_intercept_recurse) do
|
199
214
|
PryExceptionExplorer.intercept_object.disable! if PryExceptionExplorer.inline? && !PryExceptionExplorer.intercept_object.intercept_recurse?
|
200
215
|
end.add_hook(:after_session, :manage_intercept_recurse) do
|
201
216
|
PryExceptionExplorer.intercept_object.enable! if !PryExceptionExplorer.intercept_object.active?
|
217
|
+
end.add_hook(:before_session, :display_exception) do |_, _, _pry_|
|
218
|
+
_pry_.run_command "cat --ex"
|
202
219
|
end
|
203
|
-
|
220
|
+
|
204
221
|
Pry.start binding, :call_stack => ex.exception_call_stack, :hooks => hooks
|
205
222
|
end
|
206
223
|
|
207
224
|
# Set initial state
|
208
225
|
def init
|
209
|
-
|
210
|
-
|
211
|
-
PryExceptionExplorer.enabled = true
|
226
|
+
# disable EE by default
|
227
|
+
PryExceptionExplorer.enabled = false
|
212
228
|
|
213
229
|
# auto-start sessions on exceptions that would kill the program
|
214
|
-
PryExceptionExplorer.post_mortem =
|
230
|
+
PryExceptionExplorer.post_mortem = false
|
215
231
|
|
216
232
|
# default is to capture all exceptions
|
217
233
|
PryExceptionExplorer.intercept(Exception)
|
@@ -233,12 +249,15 @@ module PryExceptionExplorer
|
|
233
249
|
end
|
234
250
|
end
|
235
251
|
|
236
|
-
#
|
252
|
+
# Set up enter-exception style exception handling by default for pry sessions
|
237
253
|
Pry.config.hooks.add_hook(:before_session, :try_enable_exception_explorer) do
|
238
|
-
PryExceptionExplorer.enabled
|
239
|
-
PryExceptionExplorer.
|
254
|
+
PryExceptionExplorer.enabled = true
|
255
|
+
PryExceptionExplorer.old_inline_state = PryExceptionExplorer.inline
|
256
|
+
PryExceptionExplorer.inline = false
|
257
|
+
end.add_hook(:after_session, :restore_inline_state) do
|
258
|
+
PryExceptionExplorer.inline = PryExceptionExplorer.old_inline_state
|
240
259
|
end
|
241
|
-
|
260
|
+
|
242
261
|
# Bring in commands
|
243
262
|
Pry.config.commands.import PryExceptionExplorer::Commands
|
244
263
|
|
@@ -57,7 +57,7 @@ module PryExceptionExplorer
|
|
57
57
|
# updated target (the context of the exception)
|
58
58
|
_pry_.run_command "whereami"
|
59
59
|
elsif ex
|
60
|
-
raise Pry::CommandError, "
|
60
|
+
raise Pry::CommandError, "Exception can't be entered! (perhaps an internal exception)"
|
61
61
|
else
|
62
62
|
raise Pry::CommandError, "No exception to enter!"
|
63
63
|
end
|
@@ -34,11 +34,10 @@ class Exception
|
|
34
34
|
if PryExceptionExplorer.enabled? &&
|
35
35
|
PryExceptionExplorer.should_intercept_exception?(binding.of_caller(1), self) &&
|
36
36
|
!caller.any? { |t| t.include?("raise") } && !exception_call_stack
|
37
|
-
|
38
|
-
ex = old_exception(*args, &block)
|
39
37
|
|
38
|
+
ex = old_exception(*args, &block)
|
40
39
|
ex.exception_call_stack = binding.callers.drop(1)
|
41
|
-
ex.set_backtrace(caller
|
40
|
+
ex.set_backtrace(caller) if !ex.backtrace
|
42
41
|
|
43
42
|
PryExceptionExplorer.amend_exception_call_stack!(ex)
|
44
43
|
ex.should_intercept = true
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "pry-exception_explorer"
|
5
|
-
s.version = "0.2.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["John Mair (banisterfiend)"]
|
9
|
-
s.date = "2012-
|
9
|
+
s.date = "2012-10-04"
|
10
10
|
s.description = "Enter the context of exceptions"
|
11
11
|
s.email = "jrmair@gmail.com"
|
12
12
|
s.executables = ["pry-shim"]
|
@@ -4,10 +4,11 @@ require 'ostruct'
|
|
4
4
|
# globally accessible state
|
5
5
|
O = OpenStruct.new
|
6
6
|
|
7
|
-
|
7
|
+
|
8
8
|
|
9
9
|
prev_intercept_state = PryExceptionExplorer.intercept_object
|
10
10
|
|
11
|
+
PryExceptionExplorer.inline!
|
11
12
|
PryExceptionExplorer.enabled = true
|
12
13
|
|
13
14
|
describe PryExceptionExplorer do
|
@@ -77,36 +78,37 @@ describe PryExceptionExplorer do
|
|
77
78
|
EE.intercept_object = old
|
78
79
|
end
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
end
|
81
|
+
# * DEPRECATED * this test is no longer relevant as in-session exception handling is now restricted to enter-exception style
|
82
|
+
#
|
83
|
+
# describe "intercept_recurse" do
|
84
|
+
# it 'should NOT allow recursive (in-session) interceptions by default' do
|
85
|
+
# EE.intercept { |frame, ex| frame.klass == Toad }
|
86
|
+
|
87
|
+
# redirect_pry_io(InputTester.new("O.before_self = self",
|
88
|
+
# "Ratty.new.ratty",
|
89
|
+
# "O.after_self = self",
|
90
|
+
# "continue-exception",
|
91
|
+
# "continue-exception")) do
|
92
|
+
# Ratty.new.ratty
|
93
|
+
# end
|
94
|
+
|
95
|
+
# O.before_self.should == O.after_self
|
96
|
+
# end
|
97
|
+
|
98
|
+
# it 'should allow recursive (in-session) interceptions when :intercept_recurse => true' do
|
99
|
+
# EE.intercept { |frame, ex| frame.klass == Toad }.intercept_recurse(true)
|
100
|
+
|
101
|
+
# redirect_pry_io(InputTester.new("O.before_self = self",
|
102
|
+
# "Ratty.new.ratty",
|
103
|
+
# "O.after_self = self",
|
104
|
+
# "continue-exception",
|
105
|
+
# "continue-exception")) do
|
106
|
+
# Ratty.new.ratty
|
107
|
+
# end
|
108
|
+
|
109
|
+
# O.before_self.should.not == O.after_self
|
110
|
+
# end
|
111
|
+
# end
|
110
112
|
|
111
113
|
describe "skip" do
|
112
114
|
it 'should skip first frame with :skip => 1' do
|
@@ -179,9 +181,38 @@ describe PryExceptionExplorer do
|
|
179
181
|
O.method_name.should == :toad
|
180
182
|
end
|
181
183
|
end
|
184
|
+
|
185
|
+
describe "resetting inline EE state when leaving session" do
|
186
|
+
|
187
|
+
before do
|
188
|
+
Pry.config.hooks.add_hook(:before_session, :try_enable_exception_explorer) do
|
189
|
+
PryExceptionExplorer.enabled = true
|
190
|
+
PryExceptionExplorer.old_inline_state = PryExceptionExplorer.inline
|
191
|
+
PryExceptionExplorer.inline = false
|
192
|
+
end.add_hook(:after_session, :restore_inline_state) do
|
193
|
+
PryExceptionExplorer.inline = PryExceptionExplorer.old_inline_state
|
194
|
+
end
|
195
|
+
end
|
182
196
|
|
183
|
-
|
197
|
+
after do
|
198
|
+
Pry.config.hooks.delete_hook(:before_session, :try_enable_exception_explorer)
|
199
|
+
Pry.config.hooks.delete_hook(:after_session, :restore_inline_state)
|
200
|
+
end
|
184
201
|
|
202
|
+
it 'should have EE.inline set to false inside a session, and true outside the session' do
|
203
|
+
EE.intercept(Exception)
|
204
|
+
EE.inline!
|
205
|
+
redirect_pry_io(InputTester.new("O.in_session_inline_state = EE.inline",
|
206
|
+
"continue-exception")) do
|
207
|
+
raise "The children were crying, dreaming of the open beaks of dying birds."
|
208
|
+
end
|
209
|
+
|
210
|
+
O.in_session_inline_state.should == false
|
211
|
+
EE.inline.should == true
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "special case exception-only syntax" do
|
185
216
|
describe "single exception" do
|
186
217
|
it 'should intercept provided exceptions when given parameters (and no block)' do
|
187
218
|
my_error = Class.new(StandardError)
|
@@ -384,30 +415,32 @@ describe PryExceptionExplorer do
|
|
384
415
|
PryStackExplorer.frame_managers(O._pry_).count.should == 0
|
385
416
|
end
|
386
417
|
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
end
|
418
|
+
# * DEPRECATED * this test is no longer relevant as in-session exception handling is now restricted to enter-exception style
|
419
|
+
#
|
420
|
+
# describe "nested exceptions" do
|
421
|
+
# it 'Each successive exception interception should be managed by its own pry instance and have its own call-stack' do
|
422
|
+
# EE.intercept { |frame, ex| frame.prev.prev.method_name == :ratty }
|
423
|
+
|
424
|
+
# redirect_pry_io(InputTester.new(
|
425
|
+
# "O.first_stack_count = PryStackExplorer.frame_managers(_pry_).count",
|
426
|
+
# "O._pry_ = _pry_",
|
427
|
+
# "EE.intercept(ArgumentError)",
|
428
|
+
# "raise ArgumentError",
|
429
|
+
# "O._pry_2 = _pry_",
|
430
|
+
# "O.second_stack_count = PryStackExplorer.frame_managers(_pry_).count",
|
431
|
+
# "continue-exception",
|
432
|
+
# "continue-exception"), StringIO.new) do
|
433
|
+
# Ratty.new.ratty
|
434
|
+
# end
|
435
|
+
|
436
|
+
# O._pry_.should.not == O._pry_2
|
437
|
+
# O.first_stack_count.should == 1
|
438
|
+
# O.second_stack_count.should == 1
|
439
|
+
# PryStackExplorer.frame_managers(O._pry_).count.should == 0
|
440
|
+
# PryStackExplorer.frame_managers(O._pry_2).count.should == 0
|
441
|
+
# end
|
442
|
+
|
443
|
+
# end
|
411
444
|
|
412
445
|
describe "exit-exception" do
|
413
446
|
it 'should exit session and raise exception' do
|
@@ -112,7 +112,7 @@ describe PryExceptionExplorer do
|
|
112
112
|
PryExceptionExplorer.intercept { true }
|
113
113
|
|
114
114
|
x = :no_exception_raised
|
115
|
-
redirect_pry_io(InputTester.new("exit-exception"),
|
115
|
+
redirect_pry_io(InputTester.new("exit-exception"), StringIO.new) do
|
116
116
|
PryExceptionExplorer.wrap do
|
117
117
|
Ratty.new.ratty
|
118
118
|
end
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pry-exception_explorer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
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-
|
12
|
+
date: 2012-10-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pry-stack_explorer
|
16
|
-
requirement: &
|
16
|
+
requirement: &70365346977560 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.4.6
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70365346977560
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: bacon
|
27
|
-
requirement: &
|
27
|
+
requirement: &70365346976800 !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: *
|
35
|
+
version_requirements: *70365346976800
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake
|
38
|
-
requirement: &
|
38
|
+
requirement: &70365347034540 !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: *
|
46
|
+
version_requirements: *70365347034540
|
47
47
|
description: Enter the context of exceptions
|
48
48
|
email: jrmair@gmail.com
|
49
49
|
executables:
|
@@ -93,9 +93,9 @@ 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:
|
98
|
+
version: '0'
|
99
99
|
requirements: []
|
100
100
|
rubyforge_project:
|
101
101
|
rubygems_version: 1.8.15
|