Я был передан длительная рубиновая программа прежней версии, которая имеет многочисленные случаи
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, Прерывание или IRB:: Аварийное прекращение работы как ниже.
Проблема в том, что когда заканчивается программа Ruby, она делает это, поднимая SystemExit . Когда контроль-C приходит, он поднимает прерывание . Поскольку оба Systemexit и прерывают из из исключения , ваша обработка исключений останавливает выход или прерывание в его треках. Вот исправление:
везде, где вы можете, изменить
rescue Exception => e
# ...
end
на
rescue StandardError => e
# ...
end
для тех, которые вы не можете изменить на AddistrateError, повторно поднять исключение:
rescue Exception => e
# ...
raise
end
или, по крайней мере, повторно поднять системный сигнал и Прерывание
rescue SystemExit, Interrupt
raise
rescue Exception => e
#...
end
Любые пользовательские исключения, которые вы сделали, должен получить из AddsertrorRor , а не Исключение .
Если вы можете обернуть всю свою программу, вы можете сделать что-то вроде следующего:
trap("SIGINT") { throw :ctrl_c }
catch :ctrl_c do
begin
sleep(10)
rescue Exception
puts "Not printed"
end
end
Это в основном имеет Ctrl C Уловить / бросить вместо обработки исключений, поэтому, если существующий код уже не имеет улов: Ctrl_C в нем должно быть в порядке.
В качестве альтернативы вы можете сделать ловушку («Сигинт») {Выход! }
. Выход!
Немедленно выходит, он не вызывает исключение, поэтому код не может случайно ловить его.