从REPL访问Hunchentoot请求对象以进行调试

时间:2014-04-07 03:31:55

标签: debugging lisp common-lisp hunchentoot

我发现在编写Hunchentoot时,增量开发往往会中断。

例如,我可能会编写一个由几个函数组成的网页。如果其中一个内部函数包含调用 - 比如 - hunchentoot:post-parameters *那么我就不能轻易地在REPL中测试该函数。它会出错,因为* request *不存在,除非网页客户端调用该页面。

如果存在一些函数或其他源,那么我可以测试我的函数,这将是很好的:

>(let* ((*request* (get-previous-request-from-somewhere))
       (*session* (slot-value *request* 'hunchentoot:session)))
    (my-function <whatever params>))

是否存在类似的东西?我是否忽略了更好的调试方法?

2 个答案:

答案 0 :(得分:7)

我的临时解决方案看起来像这样:

(defparameter *save-last-request* t)
(defvar *last-request* nil)

(defun store-request ()
  (when *save-last-request*
    (setf *last-request* *request*)))

(defmacro with-last-request (&body body)
  `(let* ((*request* *last-request*)
      (*session* (slot-value *request* 'hunchentoot:session)))
    ,@body))

每次处理程序都需要调用store-request时,它可以正常工作。

答案 1 :(得分:1)

我认为最简单的事情可能是使用一个自定义请求类,它引入了一种方法来将请求持久保存到初始化链中。

这是一种方法的简单例子。请求的自定义子类,它将其状态保存在全局堆栈中。

您可以使用

将接受者设置为使用自定义请求类

(setf (acceptor-request-class acceptor ) new-value)

这样的事情

(defparameter *requests* nil)
(defclass my-request (hunchentoot:request) ())
(defmethod initialize-instance  :after ((req my-request) &key)
  (push req *requests*))

然后设置接受器请求类,以便在您创建接收器时使用此类

(setf (hunchentoot:acceptor-request-class 
        (make-instance 'hunchentoot:easy-acceptor)) 'my-request)

每次此接受者创建请求以传递给处理程序时,它都会被添加到*requests*列表中。

如果使用变量指定请求类名,则可以打开和关闭此类以进行开发/调试。

然后,您可以在测试绑定中接收来自此堆栈的请求。