Ruby异常处理问题

我正在阅读编程Ruby书,我在理解以下概念时遇到了问题:

>作者讨论了代码中可能出现的“瞬态异常”,然后建议创建自己的异常对象来处理它们.我不认为我完全理解瞬态错误是什么以及何时适合创建自己的Exception对象.他谈到定义例外时,他在Chapter 6年谈到它:

For Example, certain types of network errors might be transient.Chapter 6.Page 97. Adding Information to exceptions.

>我也很难在ruby中使用Catch and Throw.什么时候比提高救援更好?

最佳答案
你能给我们一个关于“瞬态例外”线的页面参考吗?

在任何情况下,您都可以随时创建新的异常,这样做通常很好,这样您就可以传输有关故障的更多信息.当你有低级别异常并希望将其变成对用户更有意义的东西时,这尤其好.

Ruby中的Throw / Catch实际上是一种非局部goto,就像C中的setjmp / longjmp一样,但表现得更好.您可以在任何时候想要转移执行很长时间使用它.

显然,出于同样的原因你不想使用goto,你不想这样做.你可以使用它的一个重要原因是程序需要保持运行,所以如果你遇到某些类型的错误,你可能会抛弃你正在做的所有工作并回到起点.

好吧,这似乎不是我所获得的镐书的任何一个版本的第97页,但我明白这意味着什么. ……哦,这是第三版第157页.

首先,关于“瞬态”的业务,可能会出现一些网络问题,然后自行解决,比如当BOFH拔掉网线并将其重新插入时.所以,在某些情况下,你可能想要给它几秒钟的时间安顿下来,再试一次,然后再恐慌.你会怎么做?

在这种情况下,他们会定义一种新的异常.这只是通过继承完成的:

class RetryException < RuntimeError
  # so this is a kind of RuntimeError which is a kind of Exception
  attr: ok_to_retry
  def initialize(ok_to_retry)
     @ok_to_retry
  end
end

那么如果出现问题,你可以提出这些新的可重试异常

raise RetryException.new(true), "transient read error"

现在它会向堆栈发送一些RuntimeError,但现在附加了附加信息,即标记为“是,可以重试”.

不,这是Ruby中一个非常好的东西:它具有内置的重试某些功能的能力.所以,在堆栈的某个位置,你有这个代码:

begin
   # do something that raises this exception
   do_something()
rescue RetryException => detail 
   # if the exception is one of these retryable ones, 
   # catch it here, but it in detail
   if detail.ok_to_retry  
      retry
   end
   # this means exactly the same as 'retry if detail.ok_to_retry`
   # from the book, btw

   # if it STILL doesn't work, send the exception on
   raise # just re-raises the last exception
end

转载注明原文:Ruby异常处理问题 - 代码日志