如何防止 slime 在出现某些错误时启动 sldb?

How do I prevent slime from starting sldb on certain errors?

在连接 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*的当前值,可以正常处理条件或return,此时调用调试器。例如,您可以简单地打印条件:

* (defun my-debug(condition hook)
    (declare (ignore hook))
    (print condition)
    (abort))

DEBUG-IGNORE
* (setf *debugger-hook* #'my-debug)

#<FUNCTION MY-DEBUG>

然而,由于这两个包在调试策略方面的交互方式,当 Hunchentoot 与 Slime 一起使用时,第二种方法无法使用。

在这种情况下,可以采用 solution found by Mike Ivanov,在启动 Swank 之前重新定义 swank-debugger-hook 函数:

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