aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-04-18 09:24:15 +0000
committerFuwn <[email protected]>2026-04-18 09:24:15 +0000
commitd1a91794c32df1a03f67231647e7deb4f0f81e92 (patch)
tree282add62ac4aa254f008b2da5f62f001bbc04c72
parentbuild(workers): bump wrangler compatibility_date to 2025-01-01 (diff)
downloaddue.moe-d1a91794c32df1a03f67231647e7deb4f0f81e92.tar.xz
due.moe-d1a91794c32df1a03f67231647e7deb4f0f81e92.zip
fix(settings): propagate inner json/handler errors to outer catch
Earlier fix added .catch() handlers to both fetch chains, but the outer .then body called response.json().then(...) without returning the inner promise. That meant rejections from response.json() (e.g. non-JSON response) or from the inner handler body (e.g. a throw in isEqualsJson or data access) floated unhandled. Return the inner promise so its rejection reaches the outer .catch. Also short-circuit early on !response.ok to keep the happy path at the top indentation level. Verified via a standalone promise-graph reproducer: all seven paths (outer fetch reject, non-ok response, json reject, handler throw, push fetch reject, push handler throw, happy path) are caught by their intended handler.
-rw-r--r--src/stores/settings.ts71
1 files changed, 36 insertions, 35 deletions
diff --git a/src/stores/settings.ts b/src/stores/settings.ts
index b3706b95..24d9eef0 100644
--- a/src/stores/settings.ts
+++ b/src/stores/settings.ts
@@ -197,42 +197,43 @@ settings.subscribe((value) => {
if (value.settingsSync && get(settingsSyncPulled) === true) {
fetch(root(`/api/configuration?id=${get(identity).id}`))
.then((response) => {
- if (response.ok)
- response.json().then((data) => {
- const isEqualsJson = (
- firstObject: Settings,
- secondObject: Settings,
- ) => {
- type AnyObject = { [key: string]: unknown };
-
- return (
- Object.keys(firstObject).length ===
- Object.keys(secondObject).length &&
- Object.keys(firstObject).every(
- (key) =>
- (firstObject as unknown as AnyObject)[key] ===
- (secondObject as unknown as AnyObject)[key],
- )
- );
- };
-
- if (data?.configuration && !isEqualsJson(data.configuration, value))
- fetch(root(`/api/configuration`), {
- method: "PUT",
- body: JSON.stringify(value),
+ if (!response.ok) return;
+
+ return response.json().then((data) => {
+ const isEqualsJson = (
+ firstObject: Settings,
+ secondObject: Settings,
+ ) => {
+ type AnyObject = { [key: string]: unknown };
+
+ return (
+ Object.keys(firstObject).length ===
+ Object.keys(secondObject).length &&
+ Object.keys(firstObject).every(
+ (key) =>
+ (firstObject as unknown as AnyObject)[key] ===
+ (secondObject as unknown as AnyObject)[key],
+ )
+ );
+ };
+
+ if (data?.configuration && !isEqualsJson(data.configuration, value))
+ fetch(root(`/api/configuration`), {
+ method: "PUT",
+ body: JSON.stringify(value),
+ })
+ .then((response) => {
+ if (response.ok) console.log("Pushed local configuration");
+
+ settingsSyncTimes.update((times) => ({
+ ...times,
+ lastPush: new Date(),
+ }));
})
- .then((response) => {
- if (response.ok) console.log("Pushed local configuration");
-
- settingsSyncTimes.update((times) => ({
- ...times,
- lastPush: new Date(),
- }));
- })
- .catch((error) =>
- console.error("Settings sync push failed", error),
- );
- });
+ .catch((error) =>
+ console.error("Settings sync push failed", error),
+ );
+ });
})
.catch((error) => console.error("Settings sync pull failed", error));
}