Получение Ctrl-c в рубине

Я был передан длительная рубиновая программа прежней версии, которая имеет многочисленные случаи

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:: Аварийное прекращение работы как ниже.

102
задан Cœur 9 August 2017 в 03:56
поделиться

2 ответа

Проблема в том, что когда заканчивается программа 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 , а не Исключение .

126
ответ дан 24 November 2019 в 04:28
поделиться

Если вы можете обернуть всю свою программу, вы можете сделать что-то вроде следующего:

 trap("SIGINT") { throw :ctrl_c }

 catch :ctrl_c do
 begin
    sleep(10)
 rescue Exception
    puts "Not printed"
 end
 end

Это в основном имеет Ctrl C Уловить / бросить вместо обработки исключений, поэтому, если существующий код уже не имеет улов: Ctrl_C в нем должно быть в порядке.

В качестве альтернативы вы можете сделать ловушку («Сигинт») {Выход! } . Выход! Немедленно выходит, он не вызывает исключение, поэтому код не может случайно ловить его.

71
ответ дан 24 November 2019 в 04:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: