我正在阅读编程Ruby书,我在理解以下概念时遇到了问题:
例如,某些类型的网络错误可能是暂时的。第6章。第97页。向异常添加信息。
答案 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