我无法捕获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
答案 0 :(得分:3)
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
,因此,如果两次执行相同的代码,则不会分配变量。更好地定义一个返回字符串并使用局部变量的函数。
我要捕获的是以下消息
该消息特定于您的环境如何打印错误消息,捕获起来更加困难,也许您可以绑定自己的字符串流并捕获整个输出(?),但我不建议这样做。 / p>
答案 1 :(得分:1)
您确实捕获了这种情况,因此可以重现 error 消息,但是看来您想捕获 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
顺便说一句,看来您使用的是菜谱,不是吗? :)