I don't want to rewind the stack so as to allow debugging at the root of the
problem, but I want to see it guaranteed that corrective action is executed
if there is an error, whether I choose to debug first or not.
The handler-bind version would be more elegant, but unfortunately
take-corrective-action is called before there is a chance to debug. The
unwind-protect version works as desired, and take-corrective-action is only
called after I get out of debugging.
Thanks for any suggestions!
Robert
(handler-bind ((error (lambda (c) (declare (ignore c))
(take-corrective-action))))
(do-something-that-may-raise-error))
(let ((error-happened t))
(unwind-protect
(progn
(do-something-that-may-raise-error)
(setf error-happened nil))
(when error-happened
(take-corrective-action))))
From: Joe Marshall
Subject: Re: unwind-protect, handler-bind or something else?
Date:
Message-ID: <vg51u21e.fsf@ccs.neu.edu>
"Robert Monfera" <·······@fisec.com> writes:
> The unwind-protect version works as desired, and take-corrective-action is only
> called after I get out of debugging.
If that's the desired behavior, what's the problem?
"Robert Monfera" <·······@fisec.com> writes:
> I don't want to rewind the stack so as to allow debugging at the
> root of the problem, but I want to see it guaranteed that corrective
> action is executed if there is an error, whether I choose to debug
> first or not.
>
> The handler-bind version would be more elegant, but unfortunately
> take-corrective-action is called before there is a chance to debug.
> The unwind-protect version works as desired, and
> take-corrective-action is only called after I get out of debugging.
> (handler-bind ((error (lambda (c) (declare (ignore c))
> (take-corrective-action))))
> (do-something-that-may-raise-error))
>
> (let ((error-happened t))
> (unwind-protect
> (progn
> (do-something-that-may-raise-error)
> (setf error-happened nil))
> (when error-happened
> (take-corrective-action))))
Well, if it does what you want, why don't you use it? ;-) Here is a
variant that lets you decide whether to take the corrective action or
not.
(defun test ()
(flet ((take-corrective-action ()
(format t "~&Corrector here!")))
(handler-bind ((error (lambda (c)
(cerror "Correct it." c)
(take-corrective-action)
(abort))))
(format t "~&Let's error")
(error "Hehehe."))))
Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x0655CFA0
Nils Goesche <······@cartan.de> wrote in message news:<··············@pc022.bln.elmeg.de>...
[...]
> (defun test ()
> (flet ((take-corrective-action ()
> (format t "~&Corrector here!")))
> (handler-bind ((error (lambda (c)
> (cerror "Correct it." c)
> (take-corrective-action)
> (abort))))
> (format t "~&Let's error")
> (error "Hehehe."))))
Probably it's better to have
(unwind-protect
(cerror "Correct it." c)
(take-corrective-action))
in the body of the error handler, if it must be guaranteed
that corrective action is always taken.
Also, BREAK or INVOKE-DEBUGGER might fit the bill here too
depending on what exactly is desired.
---Vassil.
"Robert Monfera" <·······@fisec.com> writes:
> I don't want to rewind the stack so as to allow debugging at the root of the
> problem, but I want to see it guaranteed that corrective action is executed
> if there is an error, whether I choose to debug first or not.
>
> The handler-bind version would be more elegant, but unfortunately
> take-corrective-action is called before there is a chance to debug.
If your only worry is terseness (sp?) then this
macro may help
(defmacro correct-after-debug (correcting-action &rest body)
(let ((error-happened (gensym "error")))
`(let ((,error-happened t))
(unwind-protect
(progn
,@body
(setf ,error-happened nil))
(when ,error-happened
,correcting-action)))))
[31]> (defun take-corrective-action () (print 'foo))
TAKE-CORRECTIVE-ACTION
[32]> (defun do-something () (print 'some))
DO-SOMETHING
[35]> (defun do-else () (print 'else))
DO-ELSE
[36]> (correct-after-debug (take-corrective-action)
(do-something)
(do-else)
(error "kaboom"))
SOME
ELSE
*** - kaboom
1. Break [37]> :a
FOO
[38]>
--
Eduardo Mu�oz
"Robert Monfera" <·······@fisec.com> wrote in message news:<······················@news2.news.adelphia.net>...
> I don't want to rewind the stack so as to allow debugging at the root of the
> problem, but I want to see it guaranteed that corrective action is executed
> if there is an error, whether I choose to debug first or not.
The usual mechanism for doing this is Lisp restarts. What are you
trying to do that cannot be done by providing a corrective restart?
Lisp debuggers show the user a list of available restarts. The
standard restart named COMMON-LISP:CONTINUE indicates a continuable
error; if such a restart is available, your debugger will probably
recognize it and say that there is a way of continuing the program.