fix(world): Einsetzen eines Orts gegen Collider-Fehler absichern

#show baute bisher scene.add, bevor player.addCollider lief: wirft
addCollider (z. B. toter Worker), blieb die Wurzel ohne active-Eintrag
in der Szene stehen — sichtbar, aber nie wieder entfernbar — und die
Ausnahme entkam synchron aus update() in die Spielschleife.

Der Collider-Handle wird jetzt vor scene.add in einem try/catch
gebaut; schlägt er fehl, bleibt die Szene unverändert, der Ort landet
in this.failed (kein erneuter Versuch) und #show überspringt ihn beim
nächsten Aufruf.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
knsoandClaude Sonnet 5 committed 2026-09-14 13:40:28 +02:00
1 parent 1c24fbf71e
commit ed5254f88e
2 files changed
+43 -5

No files matched your search

+25
View File
@@ -292,4 +292,29 @@ describe("PlaceLayer", () => {
expect(warn).toHaveBeenCalledWith(expect.stringContaining("hof"), expect.any(Error));
});
// Bruch: addCollider wirft, scene.add lief aber schon davor — die Wurzel bliebe unsichtbar und
// für immer in der Szene, ohne active-Eintrag also nie mehr entfernbar; oder die Ausnahme entkäme
// synchron aus update() in die Spielschleife (#show läuft hier direkt, nicht über die Ladekette).
it("hält die Szene unverändert und warnt, wenn addCollider beim Einsetzen wirft", async () => {
const warn = vi.spyOn(console, "warn").mockImplementation(() => {});
const model = fakeModel();
const load = vi.fn(async () => model);
const { scene, player, layer } = makeLayer(load);
player.addCollider.mockImplementation(() => { throw new Error("Worker tot"); });
layer.update(south(500));
await vi.waitFor(() => expect(layer.models.has("hof")).toBe(true));
expect(() => layer.update(south(100))).not.toThrow();
expect(warn).toHaveBeenCalledWith(expect.stringContaining("hof"), expect.any(Error));
expect(scene.children).not.toContain(model);
const callsBefore = player.addCollider.mock.calls.length;
layer.update(south(500));
layer.update(south(100));
expect(scene.children).not.toContain(model);
expect(player.addCollider.mock.calls.length).toBe(callsBefore);
});
});