如何防止 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)
在连接 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)