[Public WebGL] OT: exception handling

Glenn Maynard [email protected]
Thu Apr 5 19:33:32 PDT 2012

(To anyone that wants to save time, this is a tangent that isn't going to
lead to changes to WebGL, because it would break too much user code.  If
you don't care about this, feel free to ignore it.  I don't mind discussing
it--it's still an important topic--but I've changed the subject to avoid
derailing the on-topic thread.)

On Thu, Apr 5, 2012 at 7:55 PM, Gregg Tavares (勤) <[email protected]> wrote:

> I'm still not sure what you are suggesting. That calling any function
> during context lost throws an exception? that sounds far more surprising to
> me than returning NULL.

I think it's not surprising to anyone unless the only language they're
experienced with is C.

We've all dealt with C code which carefully checks for errors from each
function call, and we learned how easy that is to get wrong.  The industry
learned from that, and languages moved to the exception model, precisely to
avoid those problems.  That's why it's so strange to me that WebGL seemed
to jump back a decade or two to using the C style of error handling.  We
have better error handling models now.

The whole point of returning and accepting NULL is that with a few simple
> rules you have do nothing special during context lost. All the code will
> just keep running but doing nothing. If every create threw an exception now
> you'd have to have all kinds of special cases to handle every place you
> call createXXX. I don't see how that's a win.

You have to do a lot careful, special, manual error handling.  That's not a
"simple rule", it's an error-prone mess.

You don't need special cases, and you don't put exception handlers right
around the functions; you put them around the larger, higher-level
functions causing it to be called.  This is how exceptions are used.

On Thu, Apr 5, 2012 at 8:00 PM, Ben Vanik <[email protected]> wrote:

> > There are no performance issues with using exceptions for synchronous
> errors like these.
> Not true - try/catch deoptimizes every JIT - a simple if (!result) {} is
> significantly faster and results in smaller javascript code size (as the
> variable can be renamed - 'try' and 'catch' cannot be).

You're thinking of when try/catch is in a function, but exceptions are
normally caught in higher-level functions, further up the stack.  (The
entire point of exceptions is that you don't need to handle each error
individually at a low level.)  Exception catching up the call stack has no
effect on performance in functions below it.

To see the difference, compare:

https://zewt.org/~glenn/exceptions-0.html - no exceptions
https://zewt.org/~glenn/exceptions-1.html - typical, high-level exception
https://zewt.org/~glenn/exceptions-2.html - low-level exception handling

#1, the usual pattern, runs at exactly the same speed as #0 (in Chrome
18).  #2 is the case you're thinking of.

 Exception handling should be reserved for exceptional situations.

The context being lost--especially asynchronously--is as exceptional a
situation as there is.

(Also, as an aside, that's a bit of obsolete common wisdom that came into
being under C++, where throwing an exception was very expensive.  It took
me a while, when I went from C++ to languages like JS and Python, to shake
it off.  It's simply no longer relevant with modern scripting languages;
it's common practice in high-level languages to use exceptions for all
errors.  For example, all synchronous web APIs throw all errors: XHR, File
API, IndexedDB, and so on.)

>From someone who has worked with large amounts of shipping, high-quality
> code written against the current WebGL behavior: the current model works
> well. Let's not change something that is not broken and actually has many
> advantages vs. the alternatives.

No, the current model works poorly.  It's very hard to write code that
consistently handles null returns due to asynchronous context loss, and
it's even harder (almost impossible) to write tests that verify that those
null checks are comprehensive and actually work.  As Gregg points out, bugs
due to this model can be found all over the place.

However, as I've said, it's almost certainly too late to fix this, so this
is all pretty much moot.

(A thought, though: users could patch their contexts, or
WebGLRenderingContext.prototype if they're feeling more invasive, wrapping
each function to check for null and throw an exception.  That's a little
tricky, since you need to call getError to tell whether a null response is
a context lost or a legitimate null response; you'd need some tricks to
deal with that without breaking getError.  I think it could be done,
though; maybe I'll give it a shot.)

Glenn Maynard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://khronos.org/pipermail/public_webgl_khronos.org/attachments/20120405/acf74eb7/attachment.html>

More information about the public_webgl mailing list