2012年7月11日水曜日

[CommonLisp]Internal Server Errorをフックする

Web系がさっぱりわからないので、勉強がてらなにか書いてみようと思いました。
 Webアプリケーションを書く前に、プログラム中で発生した例外をフックして、Internal Server Errorとしてブラウザに表示させるようにしてみます。
(asdf:load-system :clack)
;; swank:backtraceのほうがみやすい?
(asdf:load-system :trivial-backtrace)

(defpackage :mw-debug
  (:use :cl :clack))

(in-package :mw-debug)

(defun mw-debug-debugger-hook (c hook)
  (declare (ignore hook))
  (let ((restart (find-restart 'mw-debug-restart)))
    (when (not restart)
      (error "mw-debug-restart not found"))
    (invoke-restart restart c (trivial-backtrace:print-backtrace c :output nil))))

(defclass <mw-debug> (<middleware>)
  ())

(defmethod call ((this <mw-debug>) env)
  (let ((*debugger-hook* #'mw-debug-debugger-hook))
    (restart-case (call-next this env)
      (mw-debug-restart (c bt)
 `(500
   (:content-type "text/plain")
   (,(format nil "Internal Server Error~%~%")
     ,(format nil "-- Error -------------------------------~%")
     ,(with-output-to-string (*standard-output*)
       (describe c))
     ,(format nil "-- Backtrace ---------------------------~%")
     ,bt))))))
(defun b (tmp)
  ;; 未定義の関数を呼び出す。
  (c))
(defun a ()
  (b 2))
(defun run (port)
  (clackup
   (wrap (make-instance '<mw-debug>)
  (lambda (env)
    (a)))
   :port port))

;; (run 9999)

1 件のコメント:

  1. Clackで、エラー時にInternal Server Errorにするだけであれば、clackup に :debug nil を渡すだけでできますよ。スタックトレースは吐かないですが

    返信削除