Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
656 views
in Technique[技术] by (71.8m points)

exception - Capturing Ctrl-c in ruby

I was passed a long running legacy ruby program, which has numerous occurrences of

begin
  #dosomething
rescue Exception => e
  #halt the exception's progress
end

throughout it.

Without tracking down every single possible exception these each could be handling (at least not immediately), I'd still like to be able to shut it down at times with CtrlC.

And I'd like to do so in a way which only adds to the code (so I don't affect the existing behavior, or miss an otherwise caught exception in the middle of a run.)

[CtrlC is SIGINT, or SystemExit, which appears to be equivalent to SignalException.new("INT") in Ruby's exception handling system. class SignalException < Exception, which is why this problem comes up.]

The code I would like to have written would be:

begin
  #dosomething
rescue SignalException => e
  raise e
rescue Exception => e
  #halt the exception's progress
end

EDIT: This code works, as long as you get the class of the exception you want to trap correct. That's either SystemExit, Interrupt, or IRB::Abort as below.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is that when a Ruby program ends, it does so by raising SystemExit. When a control-C comes in, it raises Interrupt. Since both SystemExit and Interrupt derive from Exception, your exception handling is stopping the exit or interrupt in its tracks. Here's the fix:

Wherever you can, change

rescue Exception => e
  # ...
end

to

rescue StandardError => e
  # ...
end

for those you can't change to StandardError, re-raise the exception:

rescue Exception => e
  # ...
  raise
end

or, at the very least, re-raise SystemExit and Interrupt

rescue SystemExit, Interrupt
  raise
rescue Exception => e
  #...
end

Any custom exceptions you have made should derive from StandardError, not Exception.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...