You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Auth failure is now a STOP condition, not a retry condition.
- isAuthError/isPermissionError/isNetworkError error classifiers
- authedJson tags auth errors with __isAuthError=true
- __isoSyncAuthBlocked global flag; block() and unblock() helpers
- 30-min timer cleared on auth failure, restarted on session recovery
- All sync triggers check __isoSyncAuthBlocked before running
- Token intercept calls __isoSyncAuthUnblock() on new valid session
- Login success calls __isoSyncAuthUnblock()
- Online event re-validates JWT before unblocking
- Smart-sync catch re-throws auth errors instead of swallowing
- All catch blocks write paused_auth (not failed) on auth errors
- Permission errors get distinct failed_permission status (no retry)
- CHANGELOG, VERSION bumped to 3.3.7
Copy file name to clipboardExpand all lines: CHANGELOG.md
+32Lines changed: 32 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,38 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
6
6
---
7
7
8
+
## [3.3.7] β 2026-06-08 β Fix: auth-gated sync state machine; stop infinite retry on auth failure
9
+
10
+
### Fixed (sync state machine β complete rebuild)
11
+
12
+
-**Auth failure is now a STOP condition, not a retry condition** β Previously any auth error (expired session, no session, 401) caused the sync to be written as `failed` and retried on the next timer tick, visibility change, or online event. The same 2009 KB payload would upload infinitely. Now any auth error immediately sets `__isoSyncAuthBlocked = true` and the entire sync pipeline halts.
13
+
-**New `isAuthError` / `isPermissionError` / `isNetworkError` classifiers** β Errors are classified before deciding to stop vs. retry. Network errors still retry; auth and permission errors do not.
14
+
-**`authedJson` now throws tagged `AuthError` objects** β When JWT is null or refresh fails, the thrown `Error` has `__isAuthError = true`. When the server returns 401/auth message, the thrown error is also tagged. All callers can now distinguish the error type.
15
+
-**30-min timer stops on auth failure, restarts on recovery** β `__isoSyncAuthBlock()` calls `clearInterval(_autoSyncTimer)`. `__isoSyncAuthUnblock()` restarts it and schedules one sync attempt.
16
+
-**All sync triggers check auth-blocked state** β `__isoAutoSync`, `__isoStartupSync`, the 30-min timer interval, the visibility-change handler, and the online-event handler all check `window.__isoSyncAuthBlocked` and return `{ reason: 'paused_auth' }` without running any upload/download.
17
+
-**Token intercept unblocks sync on new valid session** β When Supabase returns a new `access_token` (login, token refresh), the fetch interceptor calls `window.__isoSyncAuthUnblock()`, which clears the blocked flag, restarts the timer, and queues one sync attempt 2 s later.
18
+
-**Login (`__isoLogin`) unblocks sync on success** β After a successful username/password login and profile sync, `__isoSyncAuthUnblock()` is called so sync resumes without waiting for the next Supabase token intercept.
19
+
-**Online event re-validates session before unblocking** β When the network comes back and `__isoSyncAuthBlocked` is true, the handler calls `getValidJwt()` first; if a valid JWT exists, it unblocks and syncs. It does not blindly retry the upload.
20
+
-**Smart-sync catch re-throws auth errors** β The `try/catch` around `/__auth/backup/latest` in `__isoRunManualCloudSync` previously swallowed all errors as "non-fatal". Now auth errors are rethrown so they propagate to the outer catch and trigger the block.
21
+
-**Permission errors get a distinct `failed_permission` status** β These are written to sync metadata and history separately; they never trigger a retry.
22
+
-**All sync operations (`snapshot`, `upload`, `download_import`, `manual_sync`) handle auth errors uniformly** β Each catch block calls `__isoSyncAuthBlock()` and writes `paused_auth` to sync history instead of `failed`.
0 commit comments