Ruby异常处理问题

时间:2009-04-30 01:02:56

标签: ruby exception-handling

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

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

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

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

1 个答案:

答案 0 :(得分: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

因此,如果出现问题,您可以提出这些新的可重试异常

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