我应该在Erlang中使用try catch还是应该传回错误令牌?

时间:2010-02-16 14:44:22

标签: erlang

我在Erlang中编码,我对如何处理错误处理有点不确定,特别是在看到Erlang总是返回的丑陋错误之后。

我应该在Erlang中使用try catch还是应该传回错误令牌?

4 个答案:

答案 0 :(得分:6)

Erlang的基本原则是:

  

让它崩溃!

我发现避免所谓的防御性编程非常有用。在Erlang编程规则页面中更详细地解释了这个概念:

http://www.erlang.se/doc/programming_rules.shtml#HDR11

此外,即使一些Erlang错误可能有点神秘,一个很好的处理方法是 trace 它们!在Erlang中进行跟踪非常简单。看看这个快速参考:

http://aloiroberto.wordpress.com/2009/02/23/tracing-erlang-functions/

或者只是参考官方文档。

这就是说,我完全同意@jdupont。

答案 1 :(得分:6)

在顺序Erlang中进行异常处理有三种基本方法:

  1. 抛出(throw(Term)
  2. 错误(erlang:error(Reason)
  3. 退出(exit(Reason)
  4. 引发将用于非本地返回以及您希望能够处理的某些异常(可能因为它们经常发生)。当那个被提升时,你应该在它到达你的模块之前尝试阻止它。在stdlib中使用它的常用方法是抛出一个{error, Reason}类的元组,它会在将元组返回给用户之前被try...catch中的顶级函数捕获。然后,用户可以根据该返回值决定做什么。

    另一方面,

    错误指向不可恢复的异常。他们通常会要求用户更改他的代码。它们包括运行时错误,例如无法匹配的ifcase ... of分支,无法匹配或不存在的函数等。此错误的目的是崩溃,不应该在大多数情况下,在过程中被捕获或处理(让主管或监控过程接收错误消息,然后为您记录或在接口级别为用户处理)。

    当您特别希望进程终止时,将使用

    退出。有时候我不清楚何时使用退出或错误,但我给出的提示是区分意图。

    错误和退出很少应该被顺序捕获和处理(你必须确定你知道如何解决问题!),因为其他流程已经到位处理它。让它崩溃。

    (更多详情:http://learnyousomeerlang.com/errors-and-exceptions


    下一个层次是处理多进程环境中的错误。此时执行操作的标准方法是将进程链接在一起(和/或使用主管)来获取死进程及其原因:重启它们,记录消息,进行维护,在系统不断滚动时进行升级

    您可以为多个进程获取新的异常函数:exit(Pid, Reason)。这使您可以在另一个进程上调用“exit”。在这种情况下,必须通过在监视器进程中设置process_flag(trap_exit, true)来完成错误处理,之后您可以通过标准receive表达式获得退出信号。

    请注意,一种特殊的退出,即exit(Pid, kill)将终止进程,而无法捕获它。与Pid关联的其他流程应该会收到{'EXIT', killed}形式的信号。

    使用监督树是确保程序继续运行的方法。尽早崩溃也是必不可少的,以确保你不会腐败任何东西;早期有问题的代码停止运行,就越容易清理它。

答案 2 :(得分:3)

如果您可以在当地明智地处理异常,请抓住并对待它,否则让它“冒泡”。

如果您对特定异常一无所知,那么“快速失败”。

答案 3 :(得分:3)

我认为这主要是该功能的用户想要做什么的问题。标准是一个非常低级别的文件API的示例:打开文件并获取文件句柄,从传入文件句柄的文件中读取,并关闭传入文件句柄的文件。

更高级别的API是file:consult/1,您传入文件名并期望将内容重新解析为Erlang术语。中间地点是with-open-file函数,这在lisp中是常见的,您可以在其中传入一个函数,该函数使用随后打开的文件句柄作为其参数进行调用。

即使它们都打开并访问文件,但期望使用异常而不是错误标记来描述事情的方式变得越来越明智。

您希望允许程序员为成功案例编写可读代码。如果您希望文件不存在,则返回值的简单情况往往比异常处理更漂亮。如果您的成功案例是假设文件存在并且只是读取它,那么例外将确保一旦它没有停止就会崩溃。

选择任何特定方法,因为您认为Erlang有错误的错误消息似乎不是一个好的准则。