I recall some time ago, the break and backtrace capability of Hunchentoot was removed, perhaps to make it less platform dependent. But I still find myself often trying to find the origin of cryptic error messages, and adding FORMAT and BREAK statements to narrow down the problem area. What is a good way to drop in support for, say, SBCL, so that an error will break into the debugger with a backtrace, or even dump the backtrace to the log file?
Jonathon McKitrick wrote:
I recall some time ago, the break and backtrace capability of Hunchentoot was removed, perhaps to make it less platform dependent. But I still find myself often trying to find the origin of cryptic error messages, and adding FORMAT and BREAK statements to narrow down the problem area. What is a good way to drop in support for, say, SBCL, so that an error will break into the debugger with a backtrace, or even dump the backtrace to the log file?
See http://bitbucket.org/S11001001/weblocks-dev/src/tip/src/error-handler.lisp and http://bitbucket.org/S11001001/weblocks-dev/src/tip/src/request-handler.lisp...
Leslie
Thanks, I'll check these out. It looks pretty weblocks-specific, but I assume it can be adapted to hunchentoot easily enough? I'll just look for a similar method to wrap with the AROUND method.
On Tue, Sep 1, 2009 at 2:50 PM, Leslie P. Polzersky@viridian-project.de wrote:
Jonathon McKitrick wrote:
I recall some time ago, the break and backtrace capability of Hunchentoot was removed, perhaps to make it less platform dependent. But I still find myself often trying to find the origin of cryptic error messages, and adding FORMAT and BREAK statements to narrow down the problem area. What is a good way to drop in support for, say, SBCL, so that an error will break into the debugger with a backtrace, or even dump the backtrace to the log file?
See http://bitbucket.org/S11001001/weblocks-dev/src/tip/src/error-handler.lisp and http://bitbucket.org/S11001001/weblocks-dev/src/tip/src/request-handler.lisp...
Leslie
-- http://www.linkedin.com/in/polzer
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
On Wed, 2 Sep 2009 21:54:14 -0400 Jonathon McKitrick jmckitrick@gmail.com wrote:
Thanks, I'll check these out. It looks pretty weblocks-specific, but I assume it can be adapted to hunchentoot easily enough? I'll just look for a similar method to wrap with the AROUND method.
On Tue, Sep 1, 2009 at 2:50 PM, Leslie P. Polzersky@viridian-project.de wrote:
Jonathon McKitrick wrote:
I recall some time ago, the break and backtrace capability of Hunchentoot was removed, perhaps to make it less platform dependent. But I still find myself often trying to find the origin of cryptic error messages, and adding FORMAT and BREAK statements to narrow down the problem area. What is a good way to drop in support for, say, SBCL, so that an error will break into the debugger with a backtrace, or even dump the backtrace to the log file?
See http://bitbucket.org/S11001001/weblocks-dev/src/tip/src/error-handler.lisp and http://bitbucket.org/S11001001/weblocks-dev/src/tip/src/request-handler.lisp...
Leslie
For debugging purposes, I've been using the following for a while. It only extends Andreas' suggestion slightly by handling the IO-TIMEOUT condition I was experiencing in SBCL.
;;; Acceptor that provides debugging from the REPL ;;; Based on an email by Andreas Fruchs: ;;; http://common-lisp.net/pipermail/tbnl-devel/2009-April/004688.html (defclass debuggable-acceptor (acceptor) () (:documentation "An acceptor that handles errors by invoking the debugger."))
(defmethod process-connection ((*acceptor* debuggable-acceptor) (socket t)) (declare (ignore socket)) ;; Invoke the debugger on any errors except for SB-SYS:IO-TIMEOUT. ;; HTTP browsers usually leave the connection open for futher requests, ;; and Hunchentoot respects this but sets a timeout so that old connections ;; are cleaned up. (let ((*debugging-p* t)) (handler-case (call-next-method) #+sbcl (sb-sys:io-timeout (condition) (values nil condition)) (error (condition) (invoke-debugger condition)))))
(defmethod acceptor-request-dispatcher ((*acceptor* debuggable-acceptor)) (let ((dispatcher (call-next-method))) (lambda (request) (handler-bind ((error #'invoke-debugger)) (funcall dispatcher request)))))
On Thu, 3 Sep 2009 13:44:46 +1000 Daniel White daniel@whitehouse.id.au wrote:
On Wed, 2 Sep 2009 21:54:14 -0400 Jonathon McKitrick jmckitrick@gmail.com wrote:
Thanks, I'll check these out. It looks pretty weblocks-specific, but I assume it can be adapted to hunchentoot easily enough? I'll just look for a similar method to wrap with the AROUND method.
On Tue, Sep 1, 2009 at 2:50 PM, Leslie P. Polzersky@viridian-project.de wrote:
Jonathon McKitrick wrote:
I recall some time ago, the break and backtrace capability of Hunchentoot was removed, perhaps to make it less platform dependent. But I still find myself often trying to find the origin of cryptic error messages, and adding FORMAT and BREAK statements to narrow down the problem area. What is a good way to drop in support for, say, SBCL, so that an error will break into the debugger with a backtrace, or even dump the backtrace to the log file?
See http://bitbucket.org/S11001001/weblocks-dev/src/tip/src/error-handler.lisp and http://bitbucket.org/S11001001/weblocks-dev/src/tip/src/request-handler.lisp...
Leslie
For debugging purposes, I've been using the following for a while. It only extends Andreas' suggestion slightly by handling the IO-TIMEOUT condition I was experiencing in SBCL.
;;; Acceptor that provides debugging from the REPL ;;; Based on an email by Andreas Fruchs: ;;; http://common-lisp.net/pipermail/tbnl-devel/2009-April/004688.html (defclass debuggable-acceptor (acceptor) () (:documentation "An acceptor that handles errors by invoking the debugger."))
(defmethod process-connection ((*acceptor* debuggable-acceptor) (socket t)) (declare (ignore socket)) ;; Invoke the debugger on any errors except for SB-SYS:IO-TIMEOUT. ;; HTTP browsers usually leave the connection open for futher requests, ;; and Hunchentoot respects this but sets a timeout so that old connections ;; are cleaned up. (let ((*debugging-p* t)) (handler-case (call-next-method) #+sbcl (sb-sys:io-timeout (condition) (values nil condition)) (error (condition) (invoke-debugger condition)))))
(defmethod acceptor-request-dispatcher ((*acceptor* debuggable-acceptor)) (let ((dispatcher (call-next-method))) (lambda (request) (handler-bind ((error #'invoke-debugger)) (funcall dispatcher request)))))
I also have a special variable *DEBUGGING-P* defined for some other special cases I needed, so that can be safely discarded if not needed.
Jonathon McKitrick wrote:
Thanks, I'll check these out. It looks pretty weblocks-specific, but I assume it can be adapted to hunchentoot easily enough?
Weblocks is built on Hunchentoot, and I think the code shown can be used with only minor modifications.
Leslie
We have removed the backtrace support from Hunchentoot because we wanted to get rid of all non-essential system dependencies. For interactive debugging, the *BREAK-ON-SIGNALS* special variable can (should) be used, it can do what the presented acceptor subclass can do. If you really need backtraces in your log files, the trivial-backtrace [2] library may be useful.
It would be useful to have a section on debugging in the manual.
-Hans
[1] http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/var_stbrea... [2] http://common-lisp.net/project/trivial-backtrace/
On Thu, Sep 3, 2009 at 08:45, Hans Hübnerhans.huebner@gmail.com wrote:
We have removed the backtrace support from Hunchentoot because we wanted to get rid of all non-essential system dependencies. For interactive debugging, the *BREAK-ON-SIGNALS* special variable can (should) be used, it can do what the presented acceptor subclass can do. If you really need backtraces in your log files, the trivial-backtrace [2] library may be useful.
IME, *break-on-signals* didn't work too well when I was debugging my hunchentoot application. (I don't remember exactly what the problem was, sorry.) However, with just two definitions (posted in April[1]), HT gets much more debuggable in interactive use:
(defclass debuggable-acceptor (hunchentoot:acceptor) ())
(defmethod acceptor-request-dispatcher ((*acceptor* debuggable-acceptor)) (let ((dispatcher (call-next-method))) (lambda (request) (handler-bind ((error #'invoke-debugger)) (funcall dispatcher request)))))
Then, you use the hunchentoot web service with (make-instance 'debuggable-acceptor :port 4242), and you'll get a (swank) debugger every time an error condition slips through.
Hope that helps.
[1] http://common-lisp.net/pipermail/tbnl-devel/2009-April/004688.html
Hans,
As outlined before - *break-on-signals* is not a good solution. Not all conditions are errors or useful break points. If we really have to fallback to ANSI CL means for that purpose, wrapping a handler-bind like in Andreas' Solution is better - I use something similar in my code (Actually I do handle all conditions in my handlers now, because I didn't get hunchentoots error handling to do what I wanted). Documentation may help, or not; some clear protocols would be perfect :-)
Hunchentoot evolved really well towards 1.0. I really appreciate the extensibility one now gets through some clearer protocols (task- managers, request-/reply-class a. s. o.). I still see some open problems though. Hunchentoot completely misses the concept of a "representation" - instead it uses either strings or octet-streams directly in an ad hoc way. Perhaps it would be a good idea to abstract this underlying representations using a small set of extensible representation classes? Something like:
representation | / | \ | | string-representation | | | file-representation | stream-representation
A handler would then not either return a string or write itself into the stream one gets from send-headers, but it would generate (or select) a representation object and hunchentoot handles this automatically.
ciao, Jochen
-- Jochen Schmidt
Am 03.09.2009 um 08:45 schrieb Hans Hübner hans.huebner@gmail.com:
We have removed the backtrace support from Hunchentoot because we wanted to get rid of all non-essential system dependencies. For interactive debugging, the *BREAK-ON-SIGNALS* special variable can (should) be used, it can do what the presented acceptor subclass can do. If you really need backtraces in your log files, the trivial-backtrace [2] library may be useful.
It would be useful to have a section on debugging in the manual.
-Hans
[1] http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/var_stbrea... [2] http://common-lisp.net/project/trivial-backtrace/
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
Jochen, this is another email I unfortunately haven't replied to yet. Sorry again.
I can kind of understand that the concept of representation classes is tempting in terms of a clean architecture, but right now I fail to see what it would give us in practice. Could you provide an example of how one would extend this mechanism to do something that can't be done right now (or only in a "dirty" way)?
Thanks, Edi.
On Thu, Sep 3, 2009 at 9:30 AM, Jochen Schmidt jsc@crispylogics.com wrote:
Hans,
As outlined before - *break-on-signals* is not a good solution. Not all conditions are errors or useful break points. If we really have to fallback to ANSI CL means for that purpose, wrapping a handler-bind like in Andreas' Solution is better - I use something similar in my code (Actually I do handle all conditions in my handlers now, because I didn't get hunchentoots error handling to do what I wanted). Documentation may help, or not; some clear protocols would be perfect :-)
Hunchentoot evolved really well towards 1.0. I really appreciate the extensibility one now gets through some clearer protocols (task- managers, request-/reply-class a. s. o.). I still see some open problems though. Hunchentoot completely misses the concept of a "representation" - instead it uses either strings or octet-streams directly in an ad hoc way. Perhaps it would be a good idea to abstract this underlying representations using a small set of extensible representation classes? Something like:
representation | / | \ | | string-representation | | | file-representation | stream-representation
A handler would then not either return a string or write itself into the stream one gets from send-headers, but it would generate (or select) a representation object and hunchentoot handles this automatically.
ciao, Jochen
-- Jochen Schmidt
Am 03.09.2009 um 08:45 schrieb Hans Hübner hans.huebner@gmail.com:
We have removed the backtrace support from Hunchentoot because we wanted to get rid of all non-essential system dependencies. For interactive debugging, the *BREAK-ON-SIGNALS* special variable can (should) be used, it can do what the presented acceptor subclass can do. If you really need backtraces in your log files, the trivial-backtrace [2] library may be useful.
It would be useful to have a section on debugging in the manual.
-Hans
[1] http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/var_stbrea... [2] http://common-lisp.net/project/trivial-backtrace/
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel
tbnl-devel site list tbnl-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/tbnl-devel