From 9bb06cbcbfee6a79f1136d00cdeb70416f07a7bc Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 5 Nov 2026 16:08:41 +0100 Subject: [PATCH] Fix: Uncaught exception in downloadConfig --- src/config/Config.test.ts | 13 +++++++++++++ src/config/Config.ts | 17 ++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/config/Config.test.ts b/src/config/Config.test.ts index 5f8b09a27..6df037483 100644 --- a/src/config/Config.test.ts +++ b/src/config/Config.test.ts @@ -95,6 +95,19 @@ describe("Config.initWith", () => { expect(Config.get().ssla).toBe("https://example.invalid/ssla"); }); + it("falls back to the defaults when fetching config.json rejects", async () => { + // A rejected promise is what a webview gives for a missing local file. + vi.spyOn(globalThis, "fetch").mockRejectedValue( + new TypeError("Load failed"), + ); + vi.spyOn(logger, "info").mockImplementation(() => {}); + Reflect.set(Config, "internalInstance", undefined); + + await expect(Config.init()).resolves.toBeUndefined(); + + expect(Config.get().media_quality).toEqual(DEFAULT_CONFIG.media_quality); + }); + it("replaces a config initialized earlier", () => { Config.initWith({ ssla: "https://first.invalid/ssla" }); Config.initWith({ ssla: "https://second.invalid/ssla" }); diff --git a/src/config/Config.ts b/src/config/Config.ts index e2c5eb8fa..3c0f17bc9 100644 --- a/src/config/Config.ts +++ b/src/config/Config.ts @@ -140,13 +140,20 @@ export function validateConfig(config: ConfigOptions): ConfigOptions { } async function downloadConfig(fetchTarget: string): Promise { - const response = await fetch(fetchTarget); + let response: Response; + try { + response = await fetch(fetchTarget); + } catch (e) { + // The embedded package ships no config.json, and some webviews (Element X + // iOS) reject the fetch of a missing local file rather than answering 404. + logger.info(`No config at ${fetchTarget}, using defaults`, e); + // resolveConfig merges in the defaults. + return {}; + } if (isFailure(response)) { - // Lack of a config isn't an error, we should just use the defaults. - // Also treat a blank config as no config, assuming the status code is 0, because we don't get 404s from file: - // URIs so this is the only way we can not fail if the file doesn't exist when loading from a file:// URI. - return DEFAULT_CONFIG; + // resolveConfig merges in the defaults. + return {}; } return response.json();