2016-08-24 153 views
0

我想弄清楚范围问题。我有一个在AWS上设置一堆相关资源的程序功能。我需要能够捕捉失败并回滚已经建立的所有关系。我有一个try catch设置,但try块中的变量在catch中不可用,我需要它们以便我可以采取正确的步骤来回滚。Elixir尝试捕捉

try do 
    c = connection 
    cert = aws.cert 
    module = aws.create_mod(cert) 
    etc... 
rescue 
    :error -> 
     rollback(c, cert, module) 
end 

有关如何处理此问题的任何建议?

+0

认真 - - 通过gen_server来做到这一点。在一个过程中分配资源。 –

回答

1

发生这种情况是因为Elixir无法保证在引发异常时这些变量会被设置。这可能不适合你,但想象一下这样的事情。

try do 
    foo = do_something_safe() 
    bar = do_something_that_will_raise_an_error() 
    baz = do_something_else_safe() 
    ... 
rescue 
    RuntimeError -> 
    quux(foo, baz) 
end 

在前面的示例中,调用do_something_that_will_raise_an_error()会引发错误。因为它,barbaz将不会被设置。

在这种特定的情况下,你可以像做

baz = do_something_else_safe() 
foo = do_something_safe() 
try do 
    bar = do_something_that_will_raise_an_error() 
    ... 
rescue 
    RuntimeError -> 
    quux(foo, baz) 
end 

现在,即使调用do_something_that_will_raise_an_error()引发错误,你仍然有foo,并baz变量设置,并且可以用于救援区块。

基本上,设置您可以在try以外的变量。 This给出了一个try ... rescue内变量作用域的小概述。

考虑到这一点,最好是设置一位主管,并在GenServer(或者其他任何受监督的流程)中执行此操作。这样,如果它崩溃了,主管可以决定如何处理它。 Elixir和Erlang的想法都是“让它崩溃”,而不是试图在防守方面进行编程。