Elixir - 尝试/捕获 vs 尝试/救援?

标签 elixir

背景

两者 try/rescuetry/catch是 Elixir 中的错误处理技术。根据 corresponding chapter在介绍指南中。

Errors can be rescued using the try/rescue construct



另一方面,

throw and catch are reserved for situations where it is not possible to retrieve a value unless by using throw and catch.



疑问

我有一个简单的了解rescue是为了错误。虽然 catch是任何值(value)。

然而,
  • 我什么时候应该使用 Elixir 中的错误处理机制?
  • 它们之间的详细区别是什么?
  • 我应该如何选择一个在特定用例中使用?
  • 除非使用 throw 否则无法检索值的情况究竟是什么?和 catch '?
  • 最佳答案

    这是个好问题。研究了一下。

  • 它们在细节上有什么区别?

    何塞的回答:

  • Mainly, you should use throw for control-flow and reserve raise for errors, which happens on developer mistakes or under exceptional circumstances.

    In Elixir, this distinction is rather theoretical, but they matter in some languages like Ruby, where using errors/exceptions for control-flow is expensive because creating the exception object and backtrace is expensive.


  • 我应该如何选择一个在特定用例中使用?

  • 请检查此答案 Which situations require throw catch in Elixir

    不久:
    raise/rescue
    考虑将 raise/rescu 明确地与异常处理有关(一些意外情况,如程序员错误、错误的环境等)。
    throw/catch
    在您预期失败的地方很有用。
    经典的例子是:
  • 退出深度嵌套的递归调用:
    https://github.com/devinus/poison/blob/master/lib/poison/parser.ex#L34-L46
  • 正常的错误处理成本太高(可能发生在太多
    地方):
    https://github.com/michalmuskala/mongodb_ecto/blob/master/lib/mongo_ecto/objectid.ex#L29-L43
  • 您有一个非本地构造(如事务):
    https://github.com/elixir-lang/ecto/blob/428126157b1970d10f9d5233397f07c35ce69cac/test/support/test_repo.exs#L84-L98

  • 最后一个:
  • “除非使用 throw 和 catch 否则无法检索值的情况”究竟是什么?

  • 假设您正在尝试从受 Supervisor 监督的进程中运行一些代码。但该过程因意外原因而终止。
    try do
    IO.inspect MayRaiseGenServer.maybe_will_raise
    rescue
      RuntimeError -> IO.puts "there was an error"
    end
    
    MayRaiseGenServerSupervisor 监督并且由于某种原因引发了错误:
    try do
    IO.inspect MayRaiseGenServer.maybe_will_raise # <- Code after this line is no longer executed
    

    然后你可以在这里使用 catch an exception:
    try do
      IO.inspect MayRaiseGenServer.maybe_will_raise
    catch
      :exit, _ -> IO.puts "there was an error"
    end
    

    Ok.Hope 足够澄清我们正在寻找的东西。

    关于Elixir - 尝试/捕获 vs 尝试/救援?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40280887/

    相关文章:

    elixir - 在 Phoenix/Elixir 中,我应该将用户上传的文件和图像存储在哪里?

    io - 如何在 Elixir 中不按 Enter 获取单个字符?

    elixir - exrm 无法构建发布

    database - Elixir/Ecto 无法识别模型中的外键

    exception-handling - Elixir:正确的打印方式__STACKTRACE__

    macros - 将变量注入(inject)到带引号的表达式中

    functional-programming - 为什么 x = x +1 在 Elixir 中有效?

    performance - Phoenix channel 及其与套接字的关系

    elixir - 将文件解析为嵌套字典

    elixir - 在我的 elixir/phoenix 项目中执行操作后如何在 aws cloudfront 中创建失效