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 CHANGED
@@ -56,7 +56,17 @@ end
56
56
 
57
57
  desc "Run example C inline"
58
58
  task :example_c_inline do
59
- sh "pry-shim ruby -I#{direc}/lib/ #{direc}/examples/example_c_inline.rb "
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
- PryExceptionExplorer.enabled = true
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"
@@ -5,7 +5,7 @@ end
5
5
 
6
6
  require 'pry-exception_explorer'
7
7
 
8
- PryExceptionExplorer.enabled = true
8
+ EE.inline!
9
9
  PryExceptionExplorer.intercept(ArgumentError)
10
10
 
11
11
  def alpha
@@ -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
- # Ensure exceptions are intercepted at the raise site.
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.add_hook(:before_session, :set_exception_flag) do |_, _, _pry_|
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
- # enable EE
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 = true
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
- # Add a hook to properly setup EE for correct exception behaviour inside a pry session
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 = true
239
- PryExceptionExplorer.inline = false
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, "Current exception can't be entered! (perhaps an internal exception)"
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.drop(1)) if !ex.backtrace
40
+ ex.set_backtrace(caller) if !ex.backtrace
42
41
 
43
42
  PryExceptionExplorer.amend_exception_call_stack!(ex)
44
43
  ex.should_intercept = true
@@ -1,3 +1,3 @@
1
1
  module PryExceptionExplorer
2
- VERSION = "0.2.0pre4"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -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.0pre4"
5
+ s.version = "0.2.0"
6
6
 
7
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
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-09-30"
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
- PryExceptionExplorer.inline!
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
- describe "intercept_recurse" do
81
- it 'should NOT allow recursive (in-session) interceptions by default' do
82
- EE.intercept { |frame, ex| frame.klass == Toad }
83
-
84
- redirect_pry_io(InputTester.new("O.before_self = self",
85
- "Ratty.new.ratty",
86
- "O.after_self = self",
87
- "continue-exception",
88
- "continue-exception")) do
89
- Ratty.new.ratty
90
- end
91
-
92
- O.before_self.should == O.after_self
93
- end
94
-
95
- it 'should allow recursive (in-session) interceptions when :intercept_recurse => true' do
96
- EE.intercept { |frame, ex| frame.klass == Toad }.intercept_recurse(true)
97
-
98
- redirect_pry_io(InputTester.new("O.before_self = self",
99
- "Ratty.new.ratty",
100
- "O.after_self = self",
101
- "continue-exception",
102
- "continue-exception")) do
103
- Ratty.new.ratty
104
- end
105
-
106
- O.before_self.should.not == O.after_self
107
- end
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
- describe "special case exception-only syntax" do
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
- describe "nested exceptions" do
388
- it 'Each successive exception interception should be managed by its own pry instance and have its own call-stack' do
389
- EE.intercept { |frame, ex| frame.prev.prev.method_name == :ratty }
390
-
391
- redirect_pry_io(InputTester.new(
392
- "O.first_stack_count = PryStackExplorer.frame_managers(_pry_).count",
393
- "O._pry_ = _pry_",
394
- "EE.intercept(ArgumentError)",
395
- "raise ArgumentError",
396
- "O._pry_2 = _pry_",
397
- "O.second_stack_count = PryStackExplorer.frame_managers(_pry_).count",
398
- "continue-exception",
399
- "continue-exception"), StringIO.new) do
400
- Ratty.new.ratty
401
- end
402
-
403
- O._pry_.should.not == O._pry_2
404
- O.first_stack_count.should == 1
405
- O.second_stack_count.should == 1
406
- PryStackExplorer.frame_managers(O._pry_).count.should == 0
407
- PryStackExplorer.frame_managers(O._pry_2).count.should == 0
408
- end
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"), $stdout) do
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.0pre4
5
- prerelease: 5
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-09-30 00:00:00.000000000 Z
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: &70216566789760 !ruby/object:Gem::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: *70216566789760
24
+ version_requirements: *70365346977560
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bacon
27
- requirement: &70216566789080 !ruby/object:Gem::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: *70216566789080
35
+ version_requirements: *70365346976800
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &70216566788240 !ruby/object:Gem::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: *70216566788240
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: 1.3.1
98
+ version: '0'
99
99
  requirements: []
100
100
  rubyforge_project:
101
101
  rubygems_version: 1.8.15