默认情况下,Failure
例外打印如下:
# print_endline (Printexc.to_string (Failure "uh\noh"));;
Failure("uh\noh")
为了提高可读性,我们希望打印Failure
的参数,因为我们知道它应该是人类可读的。在OCaml标准库中,我们将使用以下内容初始化应用程序:
# Printexc.register_printer (function
| Failure s -> Some ("Failure: " ^ s)
| _ -> None
);;
Printexc.to_string
的新行为是:
# print_endline (Printexc.to_string (Failure "uh\noh"));;
Failure: uh
oh
大。现在,如果我们使用core_kernel库,首先我们可以看到打印异常略有不同但对人类读者来说并不是更好:
#require "core_kernel";;
# print_endline (Printexc.to_string (Failure "uh\noh"));;
(Failure "uh\
\noh")
也许我们可以覆盖这个?试试吧。
# Printexc.register_printer (function
| Failure s -> Some ("Failure: " ^ s)
| _ -> None
);;
# print_endline (Printexc.to_string (Failure "uh\noh"));;
Failure: uh
oh
这样可行,但它没有使用Core_kernel
部分的打印机。如果我们使用它,我们仍会得到相同的不可读结果:
# print_endline (Core_kernel.Exn.to_string (Failure "uh\noh"));;
(Failure "uh\
\noh")
Core_kernel.Exn
并未提供register_printer
功能。如此有效,看起来Core_kernel.Exn
确保我们不会定义自定义异常打印机。是否有其他方法或者我们是否应该使用Core_kernel.Exn
然后我们是否要显示人类可读的错误消息?
编辑:对于上下文,我们最初的问题是很好地打印嵌套的错误消息。例如,我们希望阅读以下内容:
Uncaught exception: Failure:
Uncaught exception in subprocess 1234: Failure:
something happened
trace line 1
trace line 2
trace line 1
trace line 2
trace line 3
我们使用缩进来引用和转义,而不是双引号和反斜杠转义序列。
答案 0 :(得分:1)
Base.Exn
(Core_kernel.Exn
是别名)使用Sexplib0打印机和转换器将错误打印为人类可读的s表达式。可以为Sexplib0.Exn_converter.add
的异常添加自定义性别转换器。
但是,如果您不打算将异常打印为s表达式,我确实没有理由使用Base.Exn
的打印机。
let pp_sep ppf () = Format.fprintf ppf "@ "
let pp_sexp ppf = function
| Atom s -> Format.pp_print_string ppf s
| List l ->
Format.fprintf ppf "@[<v 2> %a@]"
(Format.pp_print_list ~pp_sep pp_sexp) l
let to_string exn = Format.asprintf "%a" pp_sexp (Exn.sexp_of_t exn)