CesiumGS / CesiumGS/cesium

Hook WebGLContextCreationError to offer more detail when WebGL is not available

Open
#6,971 1 comment 0 reactions 0 assignees View on GitHub
type - enhancement
Dominant language
JavaScript
Stars
15.7k
Forks
3.9k
Avg merge
4d 6h
Merged PRs (30d)
34

Description

The good news: I found out why my corporate-managed Chrome install wasn't running Cesium (group policy sets the flag `Disable3DAPIs`), and I figured out how to get an error message out of the browser describing what happened. That's where the bad news comes in, though. Instead of returning some kind of error object or throwing an exception, `canvas.getContext()` returns null and raises an event called `webglcontextcreationerror`.

I'm opening this issue because Cesium should expose this error message to the user so they don't bang their head against obscure browser policy flags like I had to. (As @emackey [pointed out](https://groups.google.com/forum/#!topic/webgl-dev-list/19RIf8GZNVg), Chrome should kill the flag with fire as soon as possible, but that's out of my hands.)

----

On the dev side, I was going to complain about how terrible this pattern is -- synchronous function that "returns" a status via event handler! -- but the event is actually raised synchronously during the call so it does work in the constructor. For example, I added

canvas.addEventListener("webglcontextcreationerror", err => this._contextError = err.statusMessage);

to the Context constructor. This does correctly set `_contextError` to a human-readable failure reason, which can be included in the string passed to `RuntimeError` in the `throw` on line 220. I was worried this would be a complex fix, trying to add asynchronous handling to an error deep inside a chain of constructors (Viewer -> CesiumWidget -> Scene -> Context!) but it's actually a 2-line change.

The more interesting part is probably how to add test coverage. I saw that your Karma config [already has an "alternate" browser defined](https://github.com/AnalyticalGraphicsInc/cesium/blob/master/Specs/karma.conf.js#L68) but I am not a Karma expert and thus don't know how to set up a test that will only run in a custom launcher. Basically, you want a test that runs Chrome with `--disable-3d-apis` then instantiates a Context, which should throw an error containing the string "disabled by enterprise policy or commandline switch". Alternately, you can make a test for all browsers that calls `canvas.getContext("2d")` before passing the canvas to the Context constructor, which (on Chrome at least?) throws an error with the string "Canvas has an existing context of a different type". I can't guarantee that the second error condition happens on all browsers, and obviously the string is probably different. There might be other circumstances that raise `webglcontextcreationerror`, I haven't gone looking for more.

Contributor guide

Open the contributing guide

Research direction

Start in the Context constructor, especially the RuntimeError throw around line 220, and inspect Specs/karma.conf.js for the existing alternate Chrome launcher. Verify how webglcontextcreationerror is surfaced and how a browser test can reproduce it; done means the RuntimeError includes the browser's status message and coverage exists for the failure path.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
computer-graphics, testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
39/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.