나는 오래 실행되는 레거시 루비 프로그램을 통과했습니다.
begin
#dosomething
rescue Exception => e
#halt the exception's progress
end
전체적으로.
가능한 모든 예외를 추적하지 않고 (적어도 즉시는 아님) 처리 할 수 있지만 CtrlC.
그리고 코드에 추가하는 방식으로 만 수행하고 싶습니다 (따라서 기존 동작에 영향을주지 않거나 실행 중에 예외가 발견되지 않은 경우).
[ CtrlC은 SIGINT 또는 SystemExit이며 SignalException.new("INT")
Ruby의 예외 처리 시스템 과 동일한 것으로 보입니다 . class SignalException < Exception
, 이것이이 문제가 발생하는 이유입니다.]
내가 작성하고 싶은 코드는 다음과 같습니다.
begin
#dosomething
rescue SignalException => e
raise e
rescue Exception => e
#halt the exception's progress
end
편집 :이 코드는 올바르게 트랩하려는 예외의 클래스를 얻는 한 작동합니다. SystemExit, Interrupt 또는 IRB :: Abort는 아래와 같습니다.
답변
문제는 Ruby 프로그램이 종료되면 SystemExit 를 발생시켜 종료한다는 것 입니다. control-C가 들어 오면 Interrupt가 발생 합니다. SystemExit 및 Interrupt 모두 Exception 에서 파생 되므로 예외 처리는 트랙에서 종료 또는 인터럽트를 중지합니다. 수정 사항은 다음과 같습니다.
가능한 한 변경
rescue Exception => e
# ...
end
에
rescue StandardError => e
# ...
end
StandardError로 변경할 수없는 경우 예외를 다시 발생시킵니다.
rescue Exception => e
# ...
raise
end
또는 최소한 SystemExit 및 Interrupt를 다시 올립니다.
rescue SystemExit, Interrupt
raise
rescue Exception => e
#...
end
사용자 정의 예외는 Exception이 아니라 StandardError 에서 파생되어야합니다 .
답변
전체 프로그램을 래핑 할 수 있다면 다음과 같이 할 수 있습니다.
trap("SIGINT") { throw :ctrl_c }
catch :ctrl_c do
begin
sleep(10)
rescue Exception
puts "Not printed"
end
end
이것은 기본적으로 CtrlC예외 처리 대신 catch / throw를 사용하므로 기존 코드에 이미 catch : ctrl_c가 포함되어 있지 않으면 괜찮습니다.
또는 trap("SIGINT") { exit! }
. exit!
즉시 종료되며 예외가 발생하지 않으므로 코드가 실수로이를 포착 할 수 없습니다.
답변
전체 애플리케이션을 begin ... rescue
블록 (예 : Thor)으로 래핑 할 수 없다면 트랩 할 수 있습니다 SIGINT
.
trap "SIGINT" do
puts "Exiting"
exit 130
end
130은 표준 종료 코드입니다.
답변
나는 ensure
큰 효과를 사용 하고 있습니다! 이것은 당신의 물건이 끝나는 이유에 관계없이 당신의 물건이 끝날 때 일어나고 싶은 일을위한 것입니다.
답변
Ruby 에서 ZeroMQ 방식으로 Ctrl-C를 깔끔하게 처리합니다 .
#!/usr/bin/env ruby
# Shows how to handle Ctrl-C
require 'ffi-rzmq'
context = ZMQ::Context.new(1)
socket = context.socket(ZMQ::REP)
socket.bind("tcp://*:5558")
trap("INT") { puts "Shutting down."; socket.close; context.terminate; exit}
puts "Starting up"
while true do
message = socket.recv_string
puts "Message: #{message.inspect}"
socket.send_string("Message received")
end