2016-08-24 192 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的想法都是「讓它崩潰」,而不是試圖在防守方面進行編程。