From: Robert Monfera
Subject: unwind-protect, handler-bind or something else?
Date: 
Message-ID: <8sqi9.9628$Lg2.1981875@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 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? 
From: Nils Goesche
Subject: Re: unwind-protect, handler-bind or something else?
Date: 
Message-ID: <lkelbp1yuz.fsf@pc022.bln.elmeg.de>
"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
From: Vassil Nikolov
Subject: Re: unwind-protect, handler-bind or something else?
Date: 
Message-ID: <f34a0f4f.0209192353.36c8666a@posting.google.com>
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.
From: Eduardo Muñoz
Subject: Re: unwind-protect, handler-bind or something else?
Date: 
Message-ID: <un0qdvfp9.fsf@jet.es>
"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
From: Kaz Kylheku
Subject: Re: unwind-protect, handler-bind or something else?
Date: 
Message-ID: <cf333042.0209200833.69df132d@posting.google.com>
"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.