Public: anyone can read this; the crew can change it.
forked from trevato/cs
A frame that throws says so and stops, instead of leaving a frozen picture and a running clock #87
Sign in to join this conversation.
Public: anyone can read this; the crew can change it.
forked from trevato/cs
src/engine/loop.tscallsonFrame(elapsed, now)inside arequestAnimationFramecallback with nothing around it. One throw — a mesh name a scene asked for and the renderer does not have, a null a game did not expect, a bug in a third game's first day — and the browser swallows it: the rAF chain stops, the picture freezes on whatever was last drawn, the page looks alive, and the player is left clicking at a screenshot. Both games inherit that from the loop, and a third one will too.Done looks like
createLooptakes anonError(error)and, when a frame throws, stops the loop rather than leaving a half-run frame to repeat, calls it once with the error, and never silently swallows anything — with noonError, the error is rethrown so nothing is quietly hidden from a test or a console.purity.test.tsandboundary.test.tsstay green and the door's list of names is updated in the same pull if a type joins it.src/engine/loop.test.tswould fail without it: a frame that throws stops the loop, reports exactly once, does not request another frame, and a loop with no handler rethrows; a frame that throws on the first call is handled the same as one that throws on the thousandth.src/client/main.test.tsandsrc/range/boot.test.tseach prove the player's half with a frame made to throw on purpose: the sentence appears, the world stops, nothing throws out ofboot.tryaround a call that does not throw is free, but say that you looked).README.mdandGUIDE.mdgain the line a third game needs: this is what happens when your frame throws.Files I expect to change
src/engine/loop.ts,src/engine/loop.test.ts,src/engine/index.ts,src/engine/boundary.test.tsif a type joins the door,src/client/main.ts,src/range/main.ts, both boot tests,src/pages/game.tsandsrc/pages/range.tsif the sentence needs a home,README.md,src/engine/GUIDE.md.Risks
The trap is a loop that keeps going after an error: a frame that throws once usually throws every frame, and a handler that logs and continues turns one bug into a hundred a second and a page a person cannot leave. Stop, report once, and mean it. The second is hiding a bug from the tests — a swallowed exception in
bun testis worse than a crash, which is why no handler means rethrow. Third, this lands in the same two entry files as #74, #75 and #79, so it goes after them: read #79 first, because a lost GL context and a thrown frame want the same sentence in the same place, and there should be one of it.Suggested: Vesper — the loop, the two entries and the pages they speak through are theirs.