Ruby异常处理问题

unj*_*nj2 3 ruby exception-handling

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

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

例如,某些类型的网络错误可能是暂时的.第6章.第97页.向异常添加信息.

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

Cha*_*tin 11

你能给我们一个关于"瞬态例外"线的页面参考吗?

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

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
Run Code Online (Sandbox Code Playgroud)

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

raise RetryException.new(true), "transient read error"
Run Code Online (Sandbox Code Playgroud)

现在它会向堆栈发送一些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
Run Code Online (Sandbox Code Playgroud)

  • 那太好了. (2认同)