I'm trying to write a "with-logged-error" macro like so:
(defmacro with-logged-error (logger body)
"Executes args inside a handler-case and logs any errors that come up"
`(handler-case
,body
(cl:error (binda)
(log-caught-error ,logger binda))))
log-caught-error is another macro that calls the macro log-error that
finally calls the function log-msg. So far, everything works except in the
case that body really does throw (?) an error, in which case "binda" is
unbound. Here is the expanded macro (everything is inside the #:batch
package):
(macroexpand '(batch:with-logged-error batch:*libcl2-logger* (format
t "Hello ~a")))
(BLOCK #:G1517
(LET ((#:G1518 NIL))
(DECLARE (IGNORABLE #:G1518))
(TAGBODY
(HANDLER-BIND
((ERROR
(LAMBDA (SB-IMPL::TEMP) (SETQ #:G1518 SB-IMPL::TEMP) (GO
#:G1519))))
(RETURN-FROM #:G1517
(MULTIPLE-VALUE-PROG1 (FORMAT T "Hello ~a")
(SB-KERNEL:FLOAT-WAIT))))
#:G1519
(RETURN-FROM #:G1517
(LET ((BATCH::BINDA #:G1518))
(BATCH:LOG-CAUGHT-ERROR BATCH:*LIBCL2-LOGGER* BATCH::BINDA))))))
...and the error message:
The function BATCH::BINDA is undefined.
[Condition of type UNDEFINED-FUNCTION]
I suspect the problem is *really* simple, but I'm all out of ideas. I
really appreciate any help from out there.
On Apr 10, 5:21 am, Kevin L <······@tamu.edu> wrote:
> I'm trying to write a "with-logged-error" macro like so:
>
> (defmacro with-logged-error (logger body)
> "Executes args inside a handler-case and logs any errors that come up"
> `(handler-case
> ,body
> (cl:error (binda)
> (log-caught-error ,logger binda))))
A better way to do this (in many cases) is to use handler-bind, and
log but do not handle the conditions (ie don't do a control
transfer). This means you can insert these macros without perturbing
other code, which is cool. Of course you may not want that.
From: Kevin L
Subject: Re: Newbie question: macro to wrap handler-case?
Date:
Message-ID: <%HoLj.8901$_I1.5428@trnddc02>
Tim Bradshaw wrote:
> On Apr 10, 5:21 am, Kevin L <······@tamu.edu> wrote:
...[snip]...
> A better way to do this (in many cases) is to use handler-bind, and
> log but do not handle the conditions (ie don't do a control
> transfer). This means you can insert these macros without perturbing
> other code, which is cool. Of course you may not want that.
Thank you, you're right. Now I have both (with-logged-error) and
(with-logged-error-squashed). :)
Kevin L <······@tamu.edu> writes:
> I'm trying to write a "with-logged-error" macro like so:
>
> (defmacro with-logged-error (logger body)
> "Executes args inside a handler-case and logs any errors that come up"
> `(handler-case
> ,body
> (cl:error (binda)
> (log-caught-error ,logger binda))))
>
> log-caught-error is another macro that calls the macro log-error that
> finally calls the function log-msg. So far, everything works except in the
> case that body really does throw (?) an error, in which case "binda" is
> unbound. Here is the expanded macro (everything is inside the #:batch
> package):
>
> (macroexpand '(batch:with-logged-error batch:*libcl2-logger* (format
> t "Hello ~a")))
> (BLOCK #:G1517
> (LET ((#:G1518 NIL))
> (DECLARE (IGNORABLE #:G1518))
> (TAGBODY
> (HANDLER-BIND
> ((ERROR
> (LAMBDA (SB-IMPL::TEMP) (SETQ #:G1518 SB-IMPL::TEMP) (GO
> #:G1519))))
> (RETURN-FROM #:G1517
> (MULTIPLE-VALUE-PROG1 (FORMAT T "Hello ~a")
> (SB-KERNEL:FLOAT-WAIT))))
> #:G1519
> (RETURN-FROM #:G1517
> (LET ((BATCH::BINDA #:G1518))
> (BATCH:LOG-CAUGHT-ERROR BATCH:*LIBCL2-LOGGER* BATCH::BINDA))))))
>
> ...and the error message:
>
> The function BATCH::BINDA is undefined.
> [Condition of type UNDEFINED-FUNCTION]
>
> I suspect the problem is *really* simple, but I'm all out of ideas. I
> really appreciate any help from out there.
The problem is with your BATCH:LOG-CAUGHT-ERROR macro, not with
WITH-LOGGED-ERROR. Try:
(macropexpand '(BATCH:LOG-CAUGHT-ERROR BATCH:*LIBCL2-LOGGER* BATCH::BINDA))
--
__Pascal Bourguignon__ http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
From: Kevin L
Subject: Re: Newbie question: macro to wrap handler-case?
Date:
Message-ID: <KJoLj.8902$_I1.2259@trnddc02>
Pascal Bourguignon wrote:
> Kevin L <······@tamu.edu> writes:
>
>> I'm trying to write a "with-logged-error" macro like so:
>>
>> (defmacro with-logged-error (logger body)
>> "Executes args inside a handler-case and logs any errors that come up"
>> `(handler-case
>> ,body
>> (cl:error (binda)
>> (log-caught-error ,logger binda))))
>>
...[snip]...
> The problem is with your BATCH:LOG-CAUGHT-ERROR macro, not with
> WITH-LOGGED-ERROR. Try:
>
> (macropexpand '(BATCH:LOG-CAUGHT-ERROR BATCH:*LIBCL2-LOGGER*
> BATCH::BINDA))
You are right, thank you! The log-caught-error macro wasn't handling its
&rest argument(s) correctly.