2015-04-01 98 views
0

在OCaml中有可能让一个异常携带另一个异常:尼斯输出例外的例外

exception Example of exn 

但是,当这种异常是从另一个模块中提出,输出看起来是这样的:

Module.Example(_) 

对此的任何解决方案?我想要的当然是

Module.Example(Not_found) 

或类似的。

我在OUnit中遇到了这个问题,所以我无法通过良好的放置方式解决它try ... with

回答

2

建议的解决方案是不要将值作为值附带,除非需要稍后重新提升它们。

然而,有一种方法可以通过注册您自己的异常打印机来打印与您有关的异常的详细信息。这是做如下:

(* File exn.ml *) 

exception Example of exn 

let() = 
    Printexc.register_printer (function 
    | Example e -> 
     Some ("Example("^Printexc.to_string e^")") 
    | _ -> 
     None 
) 

let() = 
    try raise (Example (Example Not_found)) 
    with e -> 
    Printf.eprintf "Uh oh: %s\n%!" (Printexc.to_string e) 

编译并运行:

$ ocamlopt -o exn exn.ml 
$ ./exn 
Uh oh: Example(Example(Not_found)) 
+0

_为什么不推荐?由于打印机的问题? – 2015-04-02 16:54:09

+0

它只是与你想如何使用异常有关。我不知道捕捉它们有什么价值,也没有包裹它们。您可以抓住它们并将它们翻译成对您的图书馆用户更有意义的信息,或者如果它们已经处于用户可以接受的形式,则让它们通过。 一个满足异常情况的应用就是在我们的web后端:我们的代码中的任何地方都可以将错误/异常转换为对应于标准HTTP错误状态的异常。它们被服务器循环捕获,其他异常导致500内部服务器错误。 – 2015-04-02 18:32:43

0

我对这些细节并不熟悉,但我怀疑这个名字会被打印出来,如果它可以被可靠地检索的话。它在我的实验中从顶层打印,但不是从编译代码打印的。

一个可能的情况是使用Printexc.to_string将该异常转换为字符串,并让Example携带一个字符串。或者你可以让Example带有例外和字符串。

+0

可能是一个工作黑客现在,谢谢。 – 2015-04-01 22:16:25