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