我正在尝试编写一个宏,该宏将形式或几种表格包裹在其身体中并尝试执行它们。我希望宏能够插入调试器,类似于执行(break)
时的发生方式。
问题是我不熟悉Common Lisp捕获错误的工具。我可以用什么功能来实现这一目标?
示例用法: (break-on-error (start '#:blogdemo :port 8080))
上面的注释是正确的:可以将Web服务器配置为停止捕获和记录错误,然后破坏。
但请注意,BREAK
可以保证始终输入调试器,并且您可以随时在要测试的表单周围绑定新处理程序。例如,假设您有此处理程序捕获错误并将其记录到标准输出:
(defun main ()
(handler-case (my-function)
(error (e)
(print `(:error ,e)))))
另外,让我们定义my-function
:
(defun my-function ()
(if (zerop (random 2))
(print "success")
(error "failure")))
如果几次调用main
,您将看到"success"
或将错误打印到标准输出中。如果您想在my-function
失败时打破,尽管在main
中建立了处理程序,但可以重新定义my-function
,如下所示:
(defun my-function ()
(handler-bind ((error (lambda (condition) (break))))
(if (zerop (random 2))
(print "success")
(error "failure"))))
样式不是很好(条件被忽略等(,但这仅用于调试。现在,该函数将在错误时输入调试器。
您可以为此写一个宏。首先,将我们的处理程序定义为外部功能(用于重复使用等。此外,宏中的代码越少,越好(。顺便说一句,这一次,条件不忽略,将其打印给用户。
(defun break-on-error (condition)
(break "~a" condition))
然后简单地:
(defmacro with-active-debugger (&body body)
`(handler-bind ((error #'break-on-error))
,@body))
可以重写该功能:
(defun my-function ()
(with-active-debugger
(if (zerop (random 2))
(print "success")
(error "failure"))))