about summary refs log tree commit diff
path: root/src/state/session/agent.ts
diff options
context:
space:
mode:
authordan <dan.abramov@gmail.com>2024-08-13 18:51:49 +0100
committerGitHub <noreply@github.com>2024-08-13 18:51:49 +0100
commit57be2ea15b5bea019abf95a590640d688b7a8633 (patch)
tree6bde2e03aa3ab4e49a24a1ed8729ab771328b413 /src/state/session/agent.ts
parent7e11b862e931b5351bd3463d984ab11ee9b46522 (diff)
downloadvoidsky-57be2ea15b5bea019abf95a590640d688b7a8633.tar.zst
Don't kick to login screen on network error (#4911)
* Don't kick the user on network errors

* Track online status for RQ

* Use health endpoint

* Update test with new behavior

* Only poll while offline

* Handle races between the check and network events

* Reduce the poll kickoff interval

* Don't cache partially fetched pinned feeds

This isn't a new issue but it's more prominent with the offline handling. We're currently silently caching pinned infos that failed to fetch. This avoids showing a big spinner on failure but it also kills all feeds which is very confusing. If the request to get feed gens fails, let's fail the whole query.

Then it can be retried.
Diffstat (limited to 'src/state/session/agent.ts')
-rw-r--r--src/state/session/agent.ts27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/state/session/agent.ts b/src/state/session/agent.ts
index ea6af677c..8a48cf95e 100644
--- a/src/state/session/agent.ts
+++ b/src/state/session/agent.ts
@@ -12,6 +12,7 @@ import {tryFetchGates} from '#/lib/statsig/statsig'
 import {getAge} from '#/lib/strings/time'
 import {logger} from '#/logger'
 import {snoozeEmailConfirmationPrompt} from '#/state/shell/reminders'
+import {emitNetworkConfirmed, emitNetworkLost} from '../events'
 import {addSessionErrorLog} from './logging'
 import {
   configureModerationForAccount,
@@ -227,6 +228,7 @@ export function sessionAccountToSession(
 }
 
 // Not exported. Use factories above to create it.
+let realFetch = globalThis.fetch
 class BskyAppAgent extends BskyAgent {
   persistSessionHandler: ((event: AtpSessionEvent) => void) | undefined =
     undefined
@@ -234,6 +236,23 @@ class BskyAppAgent extends BskyAgent {
   constructor({service}: {service: string}) {
     super({
       service,
+      async fetch(...args) {
+        let success = false
+        try {
+          const result = await realFetch(...args)
+          success = true
+          return result
+        } catch (e) {
+          success = false
+          throw e
+        } finally {
+          if (success) {
+            emitNetworkConfirmed()
+          } else {
+            emitNetworkLost()
+          }
+        }
+      },
       persistSession: (event: AtpSessionEvent) => {
         if (this.persistSessionHandler) {
           this.persistSessionHandler(event)
@@ -257,7 +276,15 @@ class BskyAppAgent extends BskyAgent {
 
     // Now the agent is ready.
     const account = agentToSessionAccountOrThrow(this)
+    let lastSession = this.sessionManager.session
     this.persistSessionHandler = event => {
+      if (this.sessionManager.session) {
+        lastSession = this.sessionManager.session
+      } else if (event === 'network-error') {
+        // Put it back, we'll try again later.
+        this.sessionManager.session = lastSession
+      }
+
       onSessionChange(this, account.did, event)
       if (event !== 'create' && event !== 'update') {
         addSessionErrorLog(account.did, event)