[dojo-contributors] Promises

Kris Zyp kzyp at dojotoolkit.org
Fri Mar 5 00:39:50 EST 2010



On 3/4/2010 6:57 PM, Eugene Lazutkin wrote:
> If it is 100% backwards compatible yet smaller --- I am all for it. But
> setTimeout() hack bums me out. It is bad on so many levels including
> debugging. And throwing an error from a setTimeout() callback... What is
> the grand idea anyway? Who is going to catch it? How to catch it? Why
> bother? How can it help me to find the source of an error? Why not
> console.log() an error --- the effect looks similar? Why is this a good
> way to do the default error processing?
I did change it to console.error instead of throw per your suggestion,
see line 88.
>
> Speaking about the (default) error processing.
>
> 1) The exception processing is not a symmetric thing. While try/catch
> are symmetric, throw vs. try/catch are not. I think you make a mistake
> by wrapping all three together and declaring that all three things
> always go together. No, they are not. Usually there are many more things
> that can throw exceptions than places to catch them. The same should be
> applied to Deferreds/Promises.
>
> 2) OK, you caught an error. Now what? Not hypothetically but
> realistically? Usually you have two major choices:
>
> a) Retry an action, or rollback and retry a transaction --- 99% of cases
> we are talking about (faulty) I/O, which can be treated this way. Try to
> rollback and repeat "division by 0". :-)
>
> b) Tell a user about the problem in some way.
>
> Even (a) is frequently done by doing (b) --- asking user, if she wants
> to repeat an action.
>
> How is it done in the Real Life (tm)? You have to have an error
> reporting facilities in your application. It can be something as simple
> as using alert(), or (in reality) you have some visual design to present
> all errors in a uniform way. Even in UI-less applications usually you
> have a standardized logging or something to this effect.

Right, you do this by registering an error handler at the bottom of your
call stack.

>
> Typically in my apps I have a top-level try-catch, which does exactly
> what I described above. I rarely catch individual exceptions --- usually
> splitting them in 2-3 classes (e.g., I/O vs. everything else) are enough
> for me.
>
> Now back to Deferreds/Promises. They don't change anything. But they
> change an architecture a little bit. One way to do it is to have default
> global callbacks, which are called when nobody else is handling an
> error. If I want to be flexible, I use a stack of such callbacks ---
> only the top one is called. I can push to stack and pop from stack my
> custom error processors in different phases of my app to have some
> flexibility.
>
> I think it is a reasonable approach. I know from practice that it works.
> And the technique doesn't rely on any hacks.
>
> My proposal is to implement this default callback technique at the
> library level instead of doing setTimeout() and throw exceptions from
> nowhere. It doesn't require much code, yet flexible, practical, and
> works as advertised. ;-)
>
> Additionally, for debugging purposes, I think it would be nice to log an
> error regardless if it was processed or not. From my experience I want
> to know about it in 99% of the cases, while debugging. Make it a global
> debugging switch, or reuse an existing one. In any case it is better
> than to pepper all error callbacks with logging code.

Would it help to have a dojo.Deferred.onerror = console.error that could
be replaced as the default error handler for uncaught errors? But we
would still want to be informed about whether or not the error was
caught (preferably only onerror uncaught errors), wouldn't we? I really
don't want to strip away the users ability to catch and handle errors
with full control, and I don't see how this can be detected without a
setTimeout.

Thanks,
Kris


More information about the dojo-contributors mailing list