> Starting from Marco's patch, I wrote this new patch with which I'm > reasonably happy.
Oops, here is the correct patch obtained with the command `hg export' Sorry for the confusion. -- Reclama i tuoi diritti digitali, elimina il DRM. Approfondisci su http://www.no1984.org Reclaim your digital rights, eliminate DRM. Learn more at http://www.defectivebydesign.org/what_is_drm --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "weblocks" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/weblocks?hl=en -~----------~----~----~----~------~----~------~--~---
# HG changeset patch # User Andrea Russo <[email protected]> # Date 1239280945 -7200 # Node ID e7fb6ee7a4f8b64dc48e3094bfdce6a707c43220 # Parent d408e2863ac10b6af47cdca13d39f613640d759b Add some error handling in `handle-client-request'. We can control which restart strategy to use by default by setting the special variable `*default-restart*' to appropriate values. If this variable is `nil', we enter the debugger, so we can choose among the enstablished restarts. diff -r d408e2863ac1 -r e7fb6ee7a4f8 src/request-handler.lisp --- a/src/request-handler.lisp Tue Apr 07 20:08:45 2009 +0200 +++ b/src/request-handler.lisp Thu Apr 09 14:42:25 2009 +0200 @@ -18,8 +18,10 @@ (defvar *dispatch/render-lock* (bordeaux-threads:make-lock "*dispatch-render-lock*")) -;; remove this when Hunchentoot reintroduces *catch-errors-p* -(defvar *catch-errors-p* t) +;; Select which restart the request handler should choose. +;; Possible values are: abort-request, show-backtrace. +;; Set to NIL to invoke the debugger. +(defvar *default-restart* 'show-backtrace) (defgeneric handle-client-request (app) (:documentation @@ -50,74 +52,85 @@ Override this method (along with :before and :after specifiers) to customize behavior.")) -(defmethod handle-client-request :around (app) - (handler-bind ((error (lambda (c) - (if *catch-errors-p* - (return-from handle-client-request - (handle-error-condition app c)) - (invoke-debugger c))))) - (call-next-method))) +(defmethod handle-client-request ((app weblocks-webapp)) + (let ((*current-webapp* app) + condition) + (declare (special *current-webapp*)) + (handler-bind ((error (lambda (c) + (setf condition c) + (if *default-restart* + (invoke-restart *default-restart*) + (invoke-debugger c))))) + (restart-case + (progn + (when (null *session*) + (when (get-request-action-name) + (expired-action-handler app)) + (start-session) + (setf (webapp-session-value 'last-request-uri) :none) + (redirect (request-uri*))) + (when *maintain-last-session* + (bordeaux-threads:with-lock-held (*maintain-last-session*) + (setf *last-session* *session*))) + (let ((*request-hook* (make-instance 'request-hooks))) + (when (null (root-widget)) + (let ((root-widget (make-instance 'widget :name "root"))) + (when (weblocks-webapp-debug app) + (initialize-debug-actions)) + (setf (root-widget) root-widget) + (let (finished?) + (unwind-protect + (progn + (funcall (webapp-init-user-session) root-widget) + (setf finished? t)) + (unless finished? + (setf (root-widget) nil) + (reset-webapp-session)))) + (push 'update-dialog-on-request (request-hook :session :post-action))) + (when (cookie-in (session-cookie-name *weblocks-server*)) + (redirect (remove-session-from-uri (request-uri*))))) -(defmethod handle-client-request ((app weblocks-webapp)) - (let ((*current-webapp* app)) - (declare (special *current-webapp*)) - (when (null *session*) - (when (get-request-action-name) - (expired-action-handler app)) - (start-session) - (setf (webapp-session-value 'last-request-uri) :none) - (redirect (request-uri*))) - (when *maintain-last-session* - (bordeaux-threads:with-lock-held (*maintain-last-session*) - (setf *last-session* *session*))) - (let ((*request-hook* (make-instance 'request-hooks))) - (when (null (root-widget)) - (let ((root-widget (make-instance 'widget :name "root"))) - (when (weblocks-webapp-debug app) - (initialize-debug-actions)) - (setf (root-widget) root-widget) - (let (finished?) - (unwind-protect - (progn - (funcall (webapp-init-user-session) root-widget) - (setf finished? t)) - (unless finished? - (setf (root-widget) nil) - (reset-webapp-session)))) - (push 'update-dialog-on-request (request-hook :session :post-action))) - (when (cookie-in (session-cookie-name *weblocks-server*)) - (redirect (remove-session-from-uri (request-uri*))))) - - (let ((*weblocks-output-stream* (make-string-output-stream)) - (*uri-tokens* (make-instance 'uri-tokens :tokens (tokenize-uri (request-uri*)))) - *dirty-widgets* - *before-ajax-complete-scripts* *on-ajax-complete-scripts* - *page-dependencies* *current-page-description* - (cl-who::*indent* (weblocks-webapp-html-indent-p app))) - (declare (special *weblocks-output-stream* *dirty-widgets* - *on-ajax-complete-scripts* *uri-tokens* *page-dependencies*)) - (when (pure-request-p) - (throw 'hunchentoot::handler-done (eval-action))) - ;; a default dynamic-action hook function wraps get operations in a transaction - (eval-hook :pre-action) - (with-dynamic-hooks (:dynamic-action) - (eval-action)) - (eval-hook :post-action) - (when (and (not (ajax-request-p)) - (find *action-string* (get-parameters*) - :key #'car :test #'string-equal)) - (redirect (remove-action-from-uri (request-uri*)))) - (eval-hook :pre-render) - (with-dynamic-hooks (:dynamic-render) - (if (ajax-request-p) - (handle-ajax-request app) - (handle-normal-request app))) - (eval-hook :post-render) - (unless (ajax-request-p) - (setf (webapp-session-value 'last-request-uri) (all-tokens *uri-tokens*))) - (if (member (return-code*) *approved-return-codes*) - (get-output-stream-string *weblocks-output-stream*) - (handle-http-error app (return-code*))))))) + (let ((*weblocks-output-stream* (make-string-output-stream)) + (*uri-tokens* (make-instance 'uri-tokens :tokens (tokenize-uri (request-uri*)))) + *dirty-widgets* + *before-ajax-complete-scripts* *on-ajax-complete-scripts* + *page-dependencies* *current-page-description* + (cl-who::*indent* (weblocks-webapp-html-indent-p app))) + (declare (special *weblocks-output-stream* *dirty-widgets* + *on-ajax-complete-scripts* *uri-tokens* *page-dependencies*)) + (when (pure-request-p) + (throw 'hunchentoot::handler-done (eval-action))) + ;; a default dynamic-action hook function wraps get operations in a transaction + (eval-hook :pre-action) + (with-dynamic-hooks (:dynamic-action) + (eval-action)) + (eval-hook :post-action) + (when (and (not (ajax-request-p)) + (find *action-string* (get-parameters*) + :key #'car :test #'string-equal)) + (redirect (remove-action-from-uri (request-uri*)))) + (eval-hook :pre-render) + (with-dynamic-hooks (:dynamic-render) + (if (ajax-request-p) + (handle-ajax-request app) + (handle-normal-request app))) + (eval-hook :post-render) + (unless (ajax-request-p) + (setf (webapp-session-value 'last-request-uri) (all-tokens *uri-tokens*))) + (if (member (return-code*) *approved-return-codes*) + (get-output-stream-string *weblocks-output-stream*) + (handle-http-error app (return-code*)))))) + (abort-request () + :report "Abort this request." + (return-from handle-client-request "<h1>aborted</h1>")) + (rehandle-request () + :report "Rehandle this request." + (return-from handle-client-request + (handle-client-request app))) + (show-backtrace () + :report "Send a backtrace page to the browser." + (return-from handle-client-request + (handle-error-condition app condition))))))) (defmethod handle-ajax-request ((app weblocks-webapp)) (declare (special *weblocks-output-stream* *dirty-widgets*
