-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't use T or CONDITION in HANDLER-CASE or non-local-exiting HANDLER-BIND clauses (also affects blackbird) #108
Comments
Thanks, you are not the first person to bring this up, and it points to a lack of understanding in condition handling on my part (see orthecreedence/blackbird#8). I have read about condition handling and also specifically My error handling background typically consists of I'll review the links you sent over and also would just appreciate any feedback (or pull requests) you have on how to make the condition handling more appropriate. |
this can be considered a breaking change, per issue #108 as well as discussions at orthecreedence/blackbird#8. the idea being that cl-async no longer catches all errors and routes them to the event-cb callbacks, but instead now looks for event-info conditions (and all derivatives) and sends *only those* to the event-cb, leaving all other errors to bubble to the top (debugger). note that errors only bubble to the top if :catch-app-errors is nil! if t, *all* errors are still caught, with one important change: if :caught-errors is given (a function of one argument) when starting the event loop, then all caught errors are sent to this function to do what you will with them. in other words, event-cb is no longer the dumping ground for all conditions when catching errors, now there is a separate place. note that :caught-errors is only used when :catch-app-errors is T.
Ok, biggish updates with regard to error handling here. cl-async no longer catches errors and passes them to the nearest When using (as:with-event-loop (:catch-app-errors t :caught-errors (lambda (err) ...))
...) This allows for a production mode of sorts where a rogue error won't crash the event loop entirely, just the "thread" that the error occurred on. When using Also, I added a Also, exporting |
I've noticed there's repeating pattern of
(handler-case ... (t () ..))
and(handler-case ... (condition () ...))
in cl-async & blackbird code. Unfortunatelly this may lead to unwanted
non-local exits and some very hard-to-debug problems.
The problem is, not every condition in Common Lisp is necessarily
causing stack unwinding. For instance, WARN is implemented using
conditions, too. HANDLER-BIND can be used to handle conditions
without causing the non-local exit:
WARN
here signals aSIMPLE-WARNING
condition which still allows(princ "zzz")
form to be evaluated.HANDLER-CASE
is usually implemented internally usingHANDLER-BIND
orsome internal variant of it. It's important difference is that any
condition handled by
HANDLER-CASE
always causes a non-local exit(stack unwinding).
SIGNAL
function is the fundamental mechanism which is used to signalconditions.
ERROR
function is implemented in terms of SIGNAL, butinvokes the debugger in case the condition wasn't handled with a
non-local exit.
There's a separate superclass for conditions that are designed to
cause non-local exit,
SERIOUS-CONDITION
. It's subclasses are ERROR andsome other conditions that shouldn't be considered plain errors that
are handled as usual, such as stack overflow errors. For instance, in
SBCL:
(
TIMEOUT
here is related toSB-EXT:WITH-TIMEOUT
).Here lies the problem: handling every condition using
HANDLER-CASE
causesnon-local exit even in unwanted cases. For example:
Note that
zzz
isn't printed, althoughWARN
isn't normally supposedto alter the normal program flow. Same goes for
T
:On the other hand:
Specifying
SERIOUS-CONDITION
instead ofERROR
may not always be aright option, as you probably don't want to wrap things like stack
overflows in normal
cl-async
orblackbird
error handling mechanisms.This problem affects both
blackbird
andcl-async
. As ofcl-async
, I'm currently readying some important set of changes (see#107) that would be nice to have in
cl-async
so fixing the problemright now may probably cause some merge conflicts, so probably I
should fix it myself as the part of these changes (if you're willing
to integrate them).
See also (besides CLHS):
http://www.nhplace.com/kent/Papers/Condition-Handling-2001.html
http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
The text was updated successfully, but these errors were encountered: