异常的异常输出不错

Nice output for exception of exceptions

在 OCaml 中,可以让一个异常携带另一个异常:

exception Example of exn

但是当另一个模块引发此异常时,输出如下所示:

Module.Example(_)

有什么解决办法吗?我要的当然是

Module.Example(Not_found)

或类似。

我在 OUnit 中遇到了这个问题,所以我无法通过适当的 try ... with 来解决它。

我不熟悉细节,但我怀疑如果可以可靠地检索到该名称,它就会被打印出来。它是在我的实验中从顶层打印的,而不是从编译代码打印的。

一种可能的做法是使用 Printexc.to_string 将异常转换为字符串,并让 Example 携带一个字符串。或者您可以让 Example 同时携带异常和字符串。

推荐的解决方案是不要将异常作为值携带,除非以后需要重新引发它们。

但是,有一种方法可以通过注册您自己的异常打印机来打印对您重要的异常详细信息。这是按如下方式完成的:

(* 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))