[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] (summarizing) Canvas.getContext error handling

On Fri, Apr 29, 2011 at 2:50 PM, Cedric Vivier <cvivier@mozilla.com> wrote:
> That said, while web developers shouldn't be *forced* to handle these
> errors, it's entirely different to *allow* them to do so.

Conceptually, an exception *forces* all developers to handle errors
through a catch block.
An event *allows* only if the developer chooses to.

Your quote is out of context; I was talking about providing end-user support for diagnosing browser problems, not about merely catching an exception.  "Forcing" code to catch an exception when an error occurs is completely ordinary.

As code examples are worth 1000 words, consider :

try {
   ctx = getContext("webgl-2.0")
   if (!ctx) { /* webgl-2.0 is not supported _at all_ */
        throw "dummy exception to avoid multiple function calls that
would make this example even more verbose";
   return initializeWebGL2(ctx);
} catch (e) { /* webgl-2.0 is not supported _right now_ */
   try {
        ctx = getContext("webgl")
        if (!ctx) { /* webgl is not supported _at all_ */
            throw "dummy exception to avoid multiple function calls
that would make this example even more verbose";
        return initializeWebGL(ctx);
   } catch (e) { /* webgl is not supported _right now_ */
        ctx = getContext("2d") // oh well for this context we do not
need a try/catch at least...
        if (!ctx) { /* 2d is not supported _al all_ */
        return initialize2D(ctx);

If you don't care about the information in the exception you can just write a function.  You don't need anything convoluted.

HTMLCanvasElement.prototype.getContextWithoutExceptions = function() {
    try {
        return this.getContext.apply(this, arguments);
    } catch(e) {
        return null;
ctx = canvas.getContextWithoutExceptions("webgl");

From what Benoit described, you'll need to do this anyway if you want compatibility with current versions of Firefox.

An application is notified that a context is not supported by returning null.
The Canvas spec needs a minimal change equivalent of adding "or not
supported _right now_" to the statement above.

getContext spec does not have to even talk about the event at all :

I think you're misunderstanding the problem.  The WebGL spec defines getContext as if it owns that API, but that API is part of and defined by the Canvas spec.  WebGL talks about things like "called for the first time" and "subsequent calls".  This is all precisely defined by HTML5.

A spec that's making use of getContext should be defining it in terms of the existing Canvas spec.  That means defining things like "Return a new object for the contextId 'webgl'"--an abstract method called by the getContext spec--as 2d Canvas does.

If you ignore the normative spec for getContext, then you can indeed define getContext to do whatever you want, include dispatching an event, but that's not a good way to spec an API that makes use of another API.  This is what I'm trying to help fix.

> Whether using events or exceptions, it would be much clearer if
> getContext was adjusted--right now WebGL is essentially wedging error
> handling into a function not designed for it.

webglcontextcreationerror _is not_ an error-handling mechanism, it is
an opt-in mechanism to convey additional debugging/error information
only if desired.

Semantic nitpicks aside, it's not something that getContext supports.  This should be any easy thing to change, but the change belongs in HTML5, not by redefining getContext outside of HTML5.

For all these reasons, I believe throwing an exception changes 1.0
semantics for little benefit if any whereas it adds some clear
disadvantages (debugging experience, verbosity, goes against the
principle of least surprise).

I disagree with each these.  If throwing an exception causes problems with debuggers, the debuggers need improvement.  (Again, don't write APIs in unnatural ways to cope with temporary bugs in tools; write them correctly and the tools will improve.)  It doesn't cause verbosity (you can write code identically, if you want, as above), and I find just the opposite: it's surprising to find that I have to listen to an event to read an error message from a synchronous call.

I'm not married to throwing an exception (though I do strongly believe it's cleaner than an event); the problem is that I don't thing *either* way can be specced properly without some help from HTML5's getContext spec.

It would be nice if somebody more directly involved with WebGL could contact Ian Hickson about adding an error reporting mechanism--of any kind--to the getContext spec.

Glenn Maynard