[Public WebGL] OT: exception handling

Gregg Tavares (勤) [email protected]
Fri Apr 6 09:09:08 PDT 2012

On Thu, Apr 5, 2012 at 7:33 PM, Glenn Maynard <[email protected]> wrote:

> (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.

This is not about C vs languages with exceptions. This is about
OpenGL/WebGL, a rendering API.

> 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.

No you don't have to be careful or do lots of special handling. It's very

For 99% of WebGL programs you have to do 3 things

1) Don't attach stuff to WebGLObjects
2) When compiling/linking if you get failure, ignore that failure if the
context is lost
3) If calling getActiveAttrib or getActiveUniform check for null

That's it. Follow those rules and you're done.

99% of WebGL programs have no reason to call any other get function. If you
do not attaching things to WebGLObjects then you don't care if createXXX
returns null. the API is designed so that everything is a no-op on lost

> 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.

But I have to deal with the exception. Where as it is now I have to deal
with nothing. The logic of my code doesn't change. If I have an exception
then I get into situations where for example I expected A,B,C,D,E,F to get
called in order. I get an exception at C and now D, E, F are left undone.
All kinds of side effects can occur. Maybe A, and B pushed work do be done
into some queues that D, E and F were expected to process.. Maybe A and B
created some temporary collision objects and D, E and F were expected to
release. With exceptions all of those come into play. With WebGL's design
none of those come into play. All your code will function, WebGL calls will
just be no-ops. If you get lost context at C then C,D,E,and F still
execute. Since for 99% of WebGL programs all they are doing is pushing data
to WebGL, they have no need to query and no need to get anything then it's
no different than if the user turned his monitor off or minimized the
window. Things don't render but all the code still executes.

> 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
> handling
> 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

As pointed out above, it is exceedingly easy to write this code because you
can ignore NULL.

> , 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.)

If you want this it's easy. There's already a wrapper here (
http://www.khronos.org/webgl/wiki/Debugging) and you don't need to call
getError. You can just call gl.isContextLost. Though if you want to call
getError there's an example of wrapping it in that code.

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

More information about the public_webgl mailing list