我正在尝试编写一个宏,将一个或多个表单包装到其正文中并尝试执行它们。我想将宏放入调试器,类似于执行(break)
时的情况。
问题在于我不熟悉Common Lisp用于捕获错误的工具。我可以使用CL的哪些功能来实现这一目标?
使用示例:
(break-on-error (start '#:blogdemo :port 8080))
答案 0 :(得分:2)
以上评论是正确的:网络服务器可能被配置为停止捕获和记录错误,而是中断。
但请注意,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"))))