2013/07/27

サーバプログラムでデバッガーの起動

Common Lisp でサーバプログラムを書いている時、エラーは (handler-case ... (error (e) ...) って感じで全てにぎりつぶしたい。

でも、そうすると開発中はデバッガ起動しなくて困る。

どうしよう・・・ということで Hunchentoot のソース読んでみた。 with-simple-restart で invoke-debugger をかこめばいいみたい。

次のようにすると変数1つでデバッガの起動するしないを切り替えられるんだね。

(defvar *invoke-debugger-p* t)

(defun my-debugger (e)
(when *invoke-debugger-p*
(with-simple-restart (continue "Return from here.")
(invoke-debugger e))))

(defmacro with-debugger (&body body)
`(handler-bind ((error #'my-debugger))
,@body))

;; サーバのループ処理イメージ
(loop for socket = (accept)
do (handler-case
(with-debugger (call socket))
(error (e)
(error-handle e))))

*invoke-debugger-p* を t にしておけばエラー発生時にデバッガがあがる。そのデバッガで Continue リスタートを選べば handler-case により error-handle がちゃんと呼ばれる。

invoke-debugger はそのままだと処理が戻らないから with-simple-restart でかこんであげるってことだね。