4

从连接了 Slime 的 Clack/Hunchentoot 提供大文件时,我有时会看到类似 SB-IMPL::SIMPLE-STREAM-PERROR "Couldn't write to ~s" 之类的错误消息......这些是由浏览器过早断开连接引起的(这完全可以)。问题是每次发生时,SLDB都会弹出。这很烦人。

有没有办法可以抑制 SLDB 中的某些错误,例如上述?我仍然希望在错误日志中看到它们,但绝对不是在 SLDB 中。

4

2 回答 2

5

您可以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)))

确保您实际使用此接受器启动服务器,以便使用它。

于 2015-12-30T07:34:34.150 回答
3

更新

由于您的系统使用 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)
于 2015-12-30T11:28:53.923 回答