【问题标题】:Elixir Try Catch长生不老药试试抓
【发布时间】:2016-08-24 22:46:34
【问题描述】:

我正在尝试找出一个范围界定问题。我有一个在 AWS 上设置一堆相关资源的程序功能。我需要能够捕获故障并回滚所有已设置的关系。我有一个 try catch 设置,但是 try 块中的变量在 catch 中不可用,我需要它们以便我可以采取正确的步骤来回滚。

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

关于如何处理这个问题的任何建议?

【问题讨论】:

  • 说真的 - - 通过 gen_server 执行此操作。启动进程中的资源。

标签: elixir


【解决方案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() 的调用引发了错误,您仍然设置了 foobaz 变量,并且可以在救援块中使用它们。

基本上,设置您可以在try 之外的变量。 Thistry ... rescue 内的变量范围做了一个很好的概述。

考虑到这一点,最好设置一个主管并在GenServer(或任何其他受监督的进程)内部执行此操作。这样,如果它崩溃了,主管可以决定如何处理它。 Elixir 和 Erlang 都具有“让它崩溃”的心态,而不是试图防御性地编程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多