【问题标题】:how to catch the error message in Common Lisp?如何捕捉 Common Lisp 中的错误信息?
【发布时间】:2019-01-22 12:18:37
【问题描述】:

我无法捕获在 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

【问题讨论】:

  • 不要在代码中使用 DEFVAR...

标签: common-lisp sbcl


【解决方案1】:
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,因此如果您执行两次相同的代码,则不会分配该变量。最好定义一个返回字符串的函数,并使用局部变量。

我要捕获的是以下消息

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

【讨论】:

  • 我在这里使用“defvar”只是为了快速实验。但即便如此,错误仍然与处理程序案例一起发出,我希望它不被打印,我打印了这条消息,你告诉我如何打印,当我希望的时候。
  • @PerduGames 没问题,这句话也是为了其他人阅读答案:-)
  • @PerduGames:defvar 是用于快速实验的错误工具。
【解决方案2】:

您确实捕获了条件,因此您可以重现 错误 消息,但您似乎想要捕获 SBCL 编译警告。因此,它与条件无关。

我没有解决方案,但您应该从另一个方向搜索 IMO(如何捕获 SBCL 警告等)。

如前所述,您不应该使用defvar。您可以改用setf,即使您之前没有defvar 变量。在这种情况下,您会收到另一个警告:

; in: HANDLER-CASE (/ 3 0)
;     (SETF *MY-ERROR* C)
; ==>
;   (SETQ *MY-ERROR* C)
; 
; caught WARNING:
;   undefined variable: *MY-ERROR*
; 
; compilation unit finished
;   Undefined variable:
;     *MY-ERROR*
;   caught 1 WARNING condition
;   caught 1 STYLE-WARNING condition

顺便说一句,您似乎正在使用食谱,不是吗? :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 2020-03-18
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2010-12-06
    • 2021-12-06
    相关资源
    最近更新 更多