Skip to content

Commit 24ccb41

Browse files
authored
Add retry mechanism for CloudKit authentication
Implement exponential backoff retry logic to handle intermittent CloudKit authentication failures, particularly 421 status codes and UNKNOWN_ERROR responses. The mechanism retries up to 3 times with increasing delays (1s, 2s, 4s) to improve the reliability of CloudKit integration. - Add a retry loop with exponential backoff in the setupAuth function - Handle specific error types (421 status, UNKNOWN_ERROR) - Preserve original authentication flow for successful cases - Add wide error logging and final error handling
1 parent 8331a18 commit 24ccb41

File tree

1 file changed

+52
-6
lines changed

1 file changed

+52
-6
lines changed

src/components/Cloudkit.ts

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,64 @@ export function useCloudkit() {
3535
};
3636
}, []);
3737

38+
// useEffect(() => {
39+
// const setupAuth = async (ck: CloudKit) => {
40+
// const appleId = await ck.getDefaultContainer().setUpAuth();
41+
// if (appleId) {
42+
// setAppleSignedIn(true);
43+
// } else {
44+
// setAppleSignedIn(false);
45+
// }
46+
// };
47+
48+
// if (cloudkit) {
49+
// setupAuth(cloudkit);
50+
// }
51+
// }, [cloudkit]);
52+
3853
useEffect(() => {
3954
const setupAuth = async (ck: CloudKit) => {
40-
const appleId = await ck.getDefaultContainer().setUpAuth();
41-
if (appleId) {
42-
setAppleSignedIn(true);
43-
} else {
44-
setAppleSignedIn(false);
55+
let retries = 3;
56+
let delay = 1000; // Start with 1 second
57+
58+
while (retries > 0) {
59+
try {
60+
const appleId = await ck.getDefaultContainer().setUpAuth();
61+
if (appleId) {
62+
setAppleSignedIn(true);
63+
return; // Success
64+
}
65+
// If appleId is null but no error, it's a valid state (user not signed in)
66+
setAppleSignedIn(false);
67+
return;
68+
} catch (error: any) {
69+
console.warn(
70+
`CloudKit auth attempt failed (${4 - retries}/3):`,
71+
error
72+
);
73+
74+
// Check if the error is a 421 and we still have retries left
75+
if ((error?.status === 421 || error?.ckErrorCode === "UNKNOWN_ERROR") && retries > 1) {
76+
console.log(
77+
`Retrying CloudKit auth in ${delay}ms due to potential connection issue...`
78+
);
79+
await new Promise((resolve) => setTimeout(resolve, delay));
80+
delay *= 2; // Exponential backoff
81+
retries--;
82+
} else {
83+
// Final failure, re-throw the error to be handled elsewhere if needed
84+
setAppleSignedIn(false);
85+
throw error;
86+
}
87+
}
4588
}
4689
};
4790

4891
if (cloudkit) {
49-
setupAuth(cloudkit);
92+
setupAuth(cloudkit).catch((err) => {
93+
console.error("CloudKit authentication failed after all retries:", err);
94+
// Optionally set an error state here to show in the UI
95+
});
5096
}
5197
}, [cloudkit]);
5298

0 commit comments

Comments
 (0)