2016-08-24 3 views
0

Я пытаюсь выяснить проблему. У меня есть процедурная функция, которая создает множество связанных ресурсов на AWS. Мне нужно уловить неудачу и отменить все отношения, которые были установлены. У меня есть настройка try catch, но переменные, которые находятся в блоке try, недоступны в catch, мне они нужны, поэтому я могу предпринять правильные шаги для отката.Elixir Try Catch

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() вызовет ошибку. Из-за этого оба bar и baz.

В данном конкретном случае, вы можете быть в состоянии сделать что-то вроде

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 (или любой другой контролируемый процесс). Таким образом, если он сбой, супервизор может решить, что с ним делать. И Эликсир, и Эрланг - это образ мышления «пусть он падает» вместо того, чтобы пытаться запрограммировать оборону.