[Vm-dev] Re: Handling exceptions during callback

Igor Stasenko siguctua at gmail.com
Tue May 4 13:34:52 UTC 2010


On 4 May 2010 07:14, Andreas Raab <andreas.raab at gmx.de> wrote:
>
> Hi Igor -
>
> I don't think there's a general approach for the problem. After quickly
> checking our internal uses of callbacks I found that usage basically looks
> like this:
>
> runCallbackProcess
>        "Run the callback process"
>        [true] whileTrue:[
>                CallbackSemaphore wait.
>                [self handleCallback] ensure:[self callbackReturn].
>        ].
>
> handleCallback
>        "Handle a callback"
>        | nArgs rcvr selector args result |
>        nArgs := self callbackGetArgCount.
>        rcvr := self callbackGetArg: 1.
>        selector := self callbackGetArg: 2.
>        args := (3 to: nArgs) collect:[:i| self callbackGetArg: i].
>        result := [rcvr callback: selector asSymbol args: args] on: Error
> do:[:ex|
>                ex return: nil.
>        ].
>        self callbackResult: result.
>
> (this is slightly simplified from original code) The point there is that if
> there's an error during the callback we simply return some predefined value
> (nil in the above) and assume that the caller can deal with that default
> return value.
>
> The alternative (that I had considered but dropped as adding too much
> complexity for to little value) was having an explicit error indication
> along the lines of:
>
>        result := [rcvr callback: selector asSymbol args: args] on: Error
> do:[:ex|
>                "Signal underlying code that we failed"
>                self callbackError: ex description.
>                ex return: nil. "still sets a default return value"
>        ].
>        self callbackResult: result.
>
> But this then assumes that the callback machinery itself has some notion of
> failure which is generally not the case.
>
> The interesting point here is that since callbacks *can* fail there must be
> some way by which one can indicate to the caller that a failure has
> occurred. However, that is exactly why I decided against having the
> callbackError: call - when you handle the callbacks you absolutely need to
> wrap them properly in an error handler and do whatever is appropriate to
> return from the callback in the case of an error. And that, of course, is
> specific to the callback in question and cannot be implemented by the
> callback machinery in general.
>
> And if your callback has no way to indicate failure, then you've got two
> choices: 1) Return some madeup value or 2) Fail and die. There are really no
> other options.
>
> So the short answer to your question is that to implement a callback
> properly you *must* specify how to respond in the case of an error. It's not
> optional and in fact, you might make that part of the interface of a
> callback, i.e., *always* require an error handler for the client to indicate
> how to respond to an error. This could be as simple as something like:
>
>        Callback action:[self doSomething] ifError:[0]. "returns zero on
> errors"
>
> or it could be more complex, but you might consider making this explicitly
> part of the callback interface.
>
> The other issue in this regard is how to debug failures. We punt on this. We
> print a callstack to indicate error and then we return the default value. So
> there's no other information than the callstack. You probably want to look
> at Newspeak to find out how to debug callbacks; there must be a few 'tricks'
> for how to ensure proper debug and return semantics. We don't have any such
> uses in Teleplace at this point.
>

Thanks for detailed explanation. Indeed, there's not much what can be
done facing the requirement, that
be it error or not, you are still have to return from callback.
Since i will demand from callback users to have an unique class for
each callback type anyways,
then you can override #defaultReturnValue in a subclass and supply
value, which is safe to return.
And for extreme cases, when you want to be 100% sure, you can always
implement callback natively
and don't even bother entering an interpreter loop and passing its
arguments to a language side.
But this is a simple case, which i already having, so its not so interesting ;)

> Cheers,
>  - Andreas
>
> On 5/3/2010 4:31 PM, Igor Stasenko wrote:
>>



-- 
Best regards,
Igor Stasenko AKA sig.


More information about the Vm-dev mailing list