从连接了 Slime 的 Clack/Hunchentoot 提供大文件时,我有时会看到类似 SB-IMPL::SIMPLE-STREAM-PERROR "Couldn't write to ~s" 之类的错误消息......这些是由浏览器过早断开连接引起的(这完全可以)。问题是每次发生时,SLDB都会弹出。这很烦人。
有没有办法可以抑制 SLDB 中的某些错误,例如上述?我仍然希望在错误日志中看到它们,但绝对不是在 SLDB 中。
从连接了 Slime 的 Clack/Hunchentoot 提供大文件时,我有时会看到类似 SB-IMPL::SIMPLE-STREAM-PERROR "Couldn't write to ~s" 之类的错误消息......这些是由浏览器过早断开连接引起的(这完全可以)。问题是每次发生时,SLDB都会弹出。这很烦人。
有没有办法可以抑制 SLDB 中的某些错误,例如上述?我仍然希望在错误日志中看到它们,但绝对不是在 SLDB 中。
您可以PROCESS-CONNECTION
为您的接受器子类化并对此错误进行自己的错误处理。
让我们从定义一个自定义接受器开始:
(defclass no-error-acceptor (hunchentoot:acceptor)
())
然后我们可以创建一个包装器PROCESS-CONNECTION
来禁止打印此特定错误的消息:
(defmethod hunchentoot:process-connection ((acceptor no-error-acceptor) (socket t))
(handler-case
(call-next-method)
(sb-impl::simple-stream-perror (condition)
;; Perhaps log the error here?
nil)))
确保您实际使用此接受器启动服务器,以便使用它。
更新
由于您的系统使用 Hunchentoot,您可以将全局变量设置HUNCHENTOOT:*CATCH-ERRORS-P*
为T
. 这应该保证由 Hunchentoot 管理的代码中出现的所有条件都被 Hanchentoot 本身捕获,而不是传递给调试器。
要在任何 Common Lisp 实现中禁用调试器(无论是在 shell REPL 中还是在 Emacs 中的 Slime REPL 中),您可以使用预定义的全局变量*debugger-hook*,为其分配两个参数函数。该函数在被调用时会接收到*debugger-hook*的条件和当前值,可以处理条件或者正常返回,此时调用调试器。例如,您可以简单地打印条件:
* (defun my-debug(condition hook)
(declare (ignore hook))
(print condition)
(abort))
DEBUG-IGNORE
* (setf *debugger-hook* #'my-debug)
#<FUNCTION MY-DEBUG>
然而,当将 Hunchentoot 与 Slime 一起使用时,第二种方法无法工作,因为这两个包在调试策略方面的交互方式。
在这种情况下,可以采用Mike Ivanov 找到的解决方案swank-debugger-hook
,在启动 Swank 之前重新定义函数:
(in-package swank)
(setq swank-debugger-hook-orig #'swank-debugger-hook)
(defun swank-debugger-hook (condition hook)
(etypecase condition
(sb-int:simple-stream-error
(progn
(princ "*** Stream error" *error-output*)
(abort)))
(t (funcall swank-debugger-hook-orig condition hook))))
(in-package cl-user)
(swank:create-server :port 4008 :dont-close t)