Don't rescue overzealously. Fixes #220

This commit is contained in:
Conrad Irwin 2011-08-26 17:44:13 -07:00
parent f8b7260872
commit 04f8d4f48b
4 changed files with 33 additions and 8 deletions

View File

@ -59,6 +59,27 @@ class Pry
proc { |target_self, _| "pry #{Pry.view_clip(target_self)}:#{Dir.pwd} * " }
]
# As a REPL, we often want to catch any unexpected exceptions that may have
# been raised; however we don't want to go overboard and prevent the user
# from exiting Pry when they want to.
module RescuableException
def self.===(exception)
case exception
# Catch when the user hits ^C (Interrupt < SignalException), and assume
# that they just wanted to stop the in-progress command (just like bash etc.)
when Interrupt
true
# Don't catch signals (particularly not SIGTERM) as these are unlikely to be
# intended for pry itself. We should also make sure that Kernel#exit works.
when SystemExit, SignalException
false
# All other exceptions will be caught.
else
true
end
end
end
end
require "method_source"

View File

@ -94,7 +94,7 @@ class Pry
begin
candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
rescue Exception
rescue RescuableException
candidates = []
end
candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
@ -114,7 +114,7 @@ class Pry
begin
candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
rescue Exception
rescue RescuableException
candidates = []
end
select_message(receiver, message, candidates)
@ -126,7 +126,7 @@ class Pry
begin
candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
rescue Exception
rescue RescuableException
candidates = []
end
select_message(receiver, message, candidates)
@ -149,7 +149,7 @@ class Pry
# Foo::Bar.func
begin
candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
rescue Exception
rescue RescuableException
candidates = []
end
else
@ -158,7 +158,7 @@ class Pry
ObjectSpace.each_object(Module){|m|
begin
name = m.name.to_s
rescue Exception
rescue RescuableException
name = ""
end
next if name != "IRB::Context" and

View File

@ -181,9 +181,7 @@ class Pry
res = set_last_result(target.eval(code, Pry.eval_path, Pry.current_line), target)
res
rescue SystemExit => e
exit
rescue Exception => e
rescue RescuableException => e
set_last_exception(e, target)
ensure
update_input_history(code)

View File

@ -170,6 +170,12 @@ describe Pry do
pry_tester.rep(o)
was_called.should == true
end
it 'should not try to catch intended exceptions' do
lambda { mock_pry("raise SystemExit") }.should.raise SystemExit
# SIGTERM
lambda { mock_pry("raise SignalException.new(15)") }.should.raise SignalException
end
end
describe "repl" do