Error handling erlang中的错误传播

Error handling erlang中的错误传播,error-handling,erlang,Error Handling,Erlang,我有一个关于erlang中错误处理的概念性问题。以某个数据库调用为例,它返回{ok,Result}或{error,Err}。我有一个库,它包装对这个数据库的调用,这样我就可以做一些预处理/后处理。当这个库调用数据库时,它应该做什么 A) 发生错误时发生严重崩溃,否则返回结果: {ok, Result} = db:call(), postprocess(Result). B) 错误时发生严重崩溃,否则返回包装结果: {ok, Result} = db:call(), {ok, postproce

我有一个关于erlang中错误处理的概念性问题。以某个数据库调用为例,它返回
{ok,Result}
{error,Err}
。我有一个库,它包装对这个数据库的调用,这样我就可以做一些预处理/后处理。当这个库调用数据库时,它应该做什么

A) 发生错误时发生严重崩溃,否则返回结果:

{ok, Result} = db:call(), postprocess(Result).
B) 错误时发生严重崩溃,否则返回包装结果:

{ok, Result} = db:call(), {ok, postprocess(Result)}.
C) 实际处理错误并返回它:

case db:call() of
{ok, Result} -> {ok, postprocess(Result)};
{error, Err} -> {error, Err}
end.
D) 别的


作为后续问题,如果我有另一个库调用这个库,它应该使用什么错误传播?我的想法是,一个库应该与其返回值保持一致,我只是不清楚如何决定这些值可能是什么。

好吧,这取决于错误的类型以及应该如何处理

B)
似乎最不可能在任何地方使用。因为不能返回任何错误值,所以将其包装在
ok
元组中是没有意义的

A)
似乎是数据库连接库的一个很好的例子。例如,当与数据库的连接可能出现问题时。通常,您不希望每次有人调用您的代码时都预测到这种情况,并重新启动服务器。erlang的方法是让用户崩溃,让它的主管在良好的环境中重新启动它,然后重做请求。这种方法允许在用户端进行愉快的路径编码,并在应用程序逻辑和负责设置(并以相同方式重新启动)wright环境的代码之间实现强大的分离

使用
C)
方法(客户机只在
ok
tuple上匹配)也可以获得类似的结果,但坚持
A)
可能会让用户更清楚地了解您的期望

当库客户机可以完全(从逻辑角度)处理挖掘中的错误时,可以使用
C)
处理。一个很好的例子是,您可以在
{Key,Value}
响应上进行模式匹配,或者得到一个atom
未定义。没有返回
ok
atom,但
Key
足以找到快乐的路径。通常,这段代码的客户端可以很容易地处理
未定义的
(这是一种错误),并完全按照其逻辑进行挖掘。当然,他们只能在快乐的道路上进行模式匹配,让它崩溃。这个想法不是为了处理错误而处理错误;您只实现您的应用程序案例

还有一张纸条。在
C)
示例中,只允许处理
{error,error}
错误。如果您只想传递所有错误,这可能是更好的方法:

case db:call() of
   {ok, Result} -> 
         {ok, postprocess(Result)};
   Else -> 
         Else
end.