Macros 如果存在错误宏包装器,则公共Lisp中断(使用Clack webserver)

Macros 如果存在错误宏包装器,则公共Lisp中断(使用Clack webserver),macros,common-lisp,break,Macros,Common Lisp,Break,我试图编写一个宏,将一个或多个表单包装到其主体中,并尝试执行它们。我想将宏放入调试器,类似于执行(break)时的情况 问题是我不熟悉CommonLisp的错误捕捉工具。我可以使用CL的哪些功能来实现这一点 用法示例: (出错时中断(start'#:blogdemo:port 8080))以上评论是正确的:可以将Web服务器配置为停止捕获和记录错误,而改为中断 但请注意,它保证始终进入调试器,并且您可以始终围绕要测试的表单绑定一个新的处理程序。例如,假设您有一个处理程序,用于捕获错误并将其记录到

我试图编写一个宏,将一个或多个表单包装到其主体中,并尝试执行它们。我想将宏放入调试器,类似于执行
(break)
时的情况

问题是我不熟悉CommonLisp的错误捕捉工具。我可以使用CL的哪些功能来实现这一点

用法示例:
(出错时中断(start'#:blogdemo:port 8080))

以上评论是正确的:可以将Web服务器配置为停止捕获和记录错误,而改为中断

但请注意,它保证始终进入调试器,并且您可以始终围绕要测试的表单绑定一个新的处理程序。例如,假设您有一个处理程序,用于捕获错误并将其记录到标准输出:

(defun main ()
  (handler-case (my-function) 
    (error (e) 
      (print `(:error ,e)))))
另外,让我们定义
我的函数

(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"))))

上面的评论是正确的:可以将Web服务器配置为停止捕获和记录错误,而改为中断

但请注意,它保证始终进入调试器,并且您可以始终围绕要测试的表单绑定一个新的处理程序。例如,假设您有一个处理程序,用于捕获错误并将其记录到标准输出:

(defun main ()
  (handler-case (my-function) 
    (error (e) 
      (print `(:error ,e)))))
另外,让我们定义
我的函数

(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"))))

在出错时进入调试器是默认行为,您不需要做任何特殊的操作。然后,您必须更加具体,因为您询问的是一个非常不寻常的行为。例如,您正在运行的软件、平台、复制粘贴消息和c&c。如果您正在使用,则可以更改
*catch-errors-p*
*show-lisp-errors-p*
(请参阅)。关于错误处理:但实际上,您的问题是如何使用Web服务器处理错误。可能存在忽略错误和显示404(产品设置)、在浏览器中显示回溯或使用调试器捕获错误的设置。请参阅(Snooze不需要)。不,我不需要,这仍然是一个需要探索的领域……您是直接使用Clack/Lack还是使用web框架?我尝试了Caveman、Lucerne,最后我非常喜欢:路由只是一个函数,访问查询参数是显而易见的,它们是函数参数(当Caveman很乏味时),它有内置的设置来选择捕捉错误的位置(不需要clack错误)。由Sly(和yasnippet等)的作者编写,没有太多使用。除了端点和json输出之外,您还想做哪些更复杂的事情?在出错时输入调试器是默认行为,您不需要做任何特殊的事情。然后,您必须更加具体,因为您询问的是一个非常不寻常的行为。例如,您正在运行的软件、平台、复制粘贴消息和c&c。如果您正在使用,则可以更改
*catch-errors-p*
*show-lisp-errors-p*
(请参阅)。关于错误处理:但实际上,您的问题是如何使用Web服务器处理错误。可能存在忽略错误和显示404(产品设置)、在浏览器中显示回溯或使用调试器捕获错误的设置。请参阅(Snooze不需要)。不,我不需要,这仍然是一个需要探索的领域……您是直接使用Clack/Lack还是使用web框架?我尝试了Caveman、Lucerne,最后我非常喜欢:路由只是一个函数,访问查询参数是显而易见的,它们是函数参数(当Caveman很乏味时),它有内置的设置来选择捕捉错误的位置(不需要clack错误)。由Sly(和yasnippet等)的作者编写,没有太多使用。除了端点和json输出,您还想做什么更复杂的事情?