首页 > 解决方案 > 如何捕捉 Common Lisp 中的错误信息?

问题描述

我无法捕获在 REPL 中打印的错误消息,我希望将其作为字符串或任何其他可以稍后打印的类型,这在 Common Lisp 中是否可行?这在其他语言中很常见,例如 Javascript:

var myError = undefined;
try {
    some();
}catch(e){
    myError = e.message;
}

当然在 Common Lisp 中不会这样,毕竟它不会像 JavaScript 中那样返回错误对象,但是我想知道是否有任何方法可以捕获错误消息,所以我不需要在错误时打印它发生,但是当我想要的时候。

我正在使用: SBCL

我正在努力:

CL-USER> (handler-case (/ 3 0)
  (division-by-zero (c)
    (defvar *my-error* c)))
; in: HANDLER-CASE (/ 3 0)
;     (/ 3 0)
;
; caught STYLE-WARNING:
;   Lisp error during constant folding:
;   arithmetic error DIVISION-BY-ZERO signalled
;   Operation was (/ 3 0).
;
; compilation unit finished
;   caught 1 STYLE-WARNING condition
*MY-ERROR*
CL-USER> *my-error*
#<DIVISION-BY-ZERO {1004486093}>

我要捕获的是稍后打印的以下消息:

; in: HANDLER-CASE (/ 3 0)
;     (/ 3 0)
;
; caught STYLE-WARNING:
;   Lisp error during constant folding:
;   arithmetic error DIVISION-BY-ZERO signalled
;   Operation was (/ 3 0).
;
; compilation unit finished
;   caught 1 STYLE-WARNING condition

标签: common-lispsbcl

解决方案


CL-USER> (write *my-error* :escape nil)
arithmetic error DIVISION-BY-ZERO signalled
Operation was (/ 3 0).
#<DIVISION-BY-ZERO {100369B843}>

format使用~a指令也可以达到同样的效果:

CL-USER> (with-standard-io-syntax (format nil "~a" *my-error*))
"arithmetic error DIVISION-BY-ZERO signalled
Operation was (/ 3 0)."

请注意,您正在使用defvar,因此如果您执行两次相同的代码,则不会分配该变量。更好地定义一个返回字符串的函数,并使用局部变量。

我要捕获的是以下消息

该消息特定于您的环境如何打印错误消息,更难以捕获,也许您可​​以绑定自己的字符串流并捕获整个输出(?),但我不建议这样做。


推荐阅读