112 votes

Capture de Ctrl-C en Ruby

J'ai été passé une longue course héritage ruby programme, qui a de nombreux événements de

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

tout au long de l'.

Sans suivi en bas de chaque seule exception possible ces chacun d'entre eux pourrait être la manipulation de (au moins pas tout de suite), je voudrais encore être en mesure de l'arrêter à temps avec Ctrl-C.

Et j'aimerais le faire d'une manière qui ne fait qu'ajouter du code (donc je n'ai pas influer sur le comportement, ou de manquer une exception interceptée au moyen d'une série.)

[Ctrl-C est SIGINT, ou SystemExit, qui semble être l'équivalent de SignalException.nouvelle("INT") en Ruby exception du système de manutention. "classe SignalException < Exception", ce qui explique pourquoi ce problème se présente.]

Le code que je voudrais avoir écrit serait:

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

EDIT: Ce code fonctionne, aussi longtemps que vous avez la classe de l'exception que vous souhaitez recouvrir correcte. C'est soit SystemExit, d'Interrompre, ou de la CISR::avortement comme ci-dessous.

135voto

Wayne Conrad Points 31052

Le problème est que quand un Rubis programme se termine, il le fait en augmentant SystemExit. Lorsqu'un contrôle-C arrive, il soulève d'Interruption. Depuis deux SystemExit et Interruption de dériver à partir d' Exception, votre gestion des exceptions est l'arrêt de la sortie ou de l'interrompre dans son élan. Voici la solution:

Partout où vous le pouvez, changez

rescue Exception => e
  # ...
end

pour

rescue StandardError => e
  # ...
end

pour ceux que vous ne pouvez pas changer de StandardError, re-lever l'exception:

rescue Exception => e
  # ...
  raise
end

ou, à tout le moins, re-raise SystemExit et de l'Interruption de

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

Personnalisé exceptions que vous avez fait doit dériver de StandardError, pas d'Exception.

76voto

Logan Capaldo Points 22145

Si vous pouvez encapsuler votre programme entier, vous pouvez faire quelque chose comme ce qui suit :

Cela a essentiellement ctrl-C utiliser catch/lancer au lieu de la gestion des exceptions, alors à moins que l’actuel code déjà a un hic : ctrl_c dedans, il devrait être bon.

Sinon vous pouvez faire un . sorties immédiatement, elle ne déclenche pas d’exception si le code ne peut pas l’attraper accidentellement.

42voto

Erik Nomitch Points 320

Si vous ne pouvez pas envelopper votre application toute en un bloc (par exemple, Thor) vous pouvez piéger juste :

130 est un code de sortie standard.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X