From 9813a3e8d96b1eb7252c36fcdec3bec5b916fb24 Mon Sep 17 00:00:00 2001 From: Nibu Date: Mon, 9 Nov 2026 23:08:48 +0000 Subject: [PATCH] Scene: a throwing ray-march createScene goes to onCompileFail create() called the ray-march createScene after the try, so a throw while building it escaped onCompileFail and the CSS ground was never kept. The call now sits inside the try with the other styles. Co-Authored-By: Claude Sonnet 5.5 --- src/app/features/scene/index.test.ts | 15 +++++++++++++++ src/app/features/scene/index.ts | 11 ++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/app/features/scene/index.test.ts b/src/app/features/scene/index.test.ts index 6c3d034a..005bcbf0 100644 --- a/src/app/features/scene/index.test.ts +++ b/src/app/features/scene/index.test.ts @@ -162,4 +162,19 @@ describe('startBackgroundScene follows the sky state', () => { await flush(); expect(createScene).toHaveBeenCalledOnce(); }); + + it('keeps the ground and reports a ray-march scene that throws while being created', async () => { + const boom = new Error('shader link failed'); + createScene.mockImplementation(() => { + throw boom; + }); + const onCompileFail = vi.fn(); + const scene = await startBackgroundScene({ ...config, style: 'raymarch' }, caps, { + canvas, + onCompileFail, + }); + expect(scene).toBeNull(); + expect(onCompileFail).toHaveBeenCalledOnce(); + expect(onCompileFail).toHaveBeenCalledWith(boom); + }); }); diff --git a/src/app/features/scene/index.ts b/src/app/features/scene/index.ts index 3cc42486..4eda80cd 100644 --- a/src/app/features/scene/index.ts +++ b/src/app/features/scene/index.ts @@ -21,10 +21,9 @@ async function create( options: StartOptions & { tier: SceneTier }, state: SkyState ): Promise { - let createScene: (o: SceneOptions) => Scene | null; try { - if (config?.style === 'raymarch') createScene = (await import('./Scene')).createScene; - else if (config?.style === 'terrain') { + if (config?.style === 'raymarch') return (await import('./Scene')).createScene(options); + if (config?.style === 'terrain') { const { createTerrainScene } = await import('./terrain/Terrain'); const sky = terrainSkyFor(state); const scene = createTerrainScene({ ...options, ...sky }); @@ -32,15 +31,13 @@ async function create( if (scene) return scene; const { createTerrainSkyScene } = await import('./terrain/TerrainSky2D'); return createTerrainSkyScene({ ...options, ...sky }); - } else { - const { createRidgeScene } = await import('./ridge/Ridge'); - return createRidgeScene({ ...options, sky: ridgeSkyFor(state) }); } + const { createRidgeScene } = await import('./ridge/Ridge'); + return createRidgeScene({ ...options, sky: ridgeSkyFor(state) }); } catch (e) { options.onCompileFail?.(e instanceof Error ? e : new Error(String(e))); return null; } - return createScene(options); } /** -- 2.47.3