【问题标题】:How to define custom exception printers using Janestreet Core?如何使用 Janestreet Core 定义自定义异常打印机?
【发布时间】:2018-11-19 00:22:51
【问题描述】:

默认情况下,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

我们使用缩进进行引用和转义,而不是双引号和反斜杠转义序列。

【问题讨论】:

    标签: ocaml core


    【解决方案1】:

    Base.ExnCore_kernel.Exn 是别名)使用 Sexplib0 打印机和转换器将错误打印为人类可读的 s 表达式。可以为 Sexplib0.Exn_converter.add 的异常添加自定义 sexp 转换器。

    但是,如果您不打算将异常打印为 s 表达式,我认为确实没有理由使用 Base.Exn 的打印机。

    编辑:由于问题似乎是 S 表达式的打印,一种解决方案可能是使用 Base.Exn.sexp_of,然后插入一个不会转义字符串或打印括号的自定义 S 表达式打印机:

    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)
    

    【讨论】:

    • 我明白了。不幸的是,一旦存在嵌套异常,S 表达式就不再是人类可读的,例如to_string (Failure (to_string e))。添加此作为示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多