Design UI/async code so it fails safely, cleans up deterministically, and recovers when the environment changes.
Apply these rules: 1) Gate irreversible transitions on success
const { detach } = cloud;
async function resume(sessionId: string) {
try {
// Resume local state first; only then detach cloud.
await restoreLocalSession(sessionId);
detach();
} catch (e) {
// On failure, keep cloud attached so user can retry.
throw e;
}
}
2) Make cleanup robust to missing events
pointerup, visibilitychange, etc. will always fire.3) Implement explicit retry points tied to reconnection/environment changes
If you consistently (a) sequence side effects after success, (b) self-terminate when events don’t arrive, and (c) retry on reconnection, the codebase will handle real-world failure scenarios gracefully.