Ver Fonte

fix(tihao): 看板请求对 FMode 偶发空响应做有限重试

Devin há 2 meses atrás
pai
commit
ea77453642
1 ficheiros alterados com 45 adições e 21 exclusões
  1. 45 21
      src/app/services/tihao-progress.service.ts

+ 45 - 21
src/app/services/tihao-progress.service.ts

@@ -69,6 +69,14 @@ export interface SessionUser {
   name: string;
 }
 
+interface FnResponse {
+  code?: number;
+  success?: boolean;
+  error?: string;
+  message?: string;
+  data?: unknown;
+}
+
 @Injectable({ providedIn: 'root' })
 export class TihaoProgressService {
   get sessionToken(): string {
@@ -118,27 +126,43 @@ export class TihaoProgressService {
 
   private async callFunction<T>(action: string, params: Record<string, unknown>): Promise<T> {
     const token = this.sessionToken;
-    const resp = await fetch(`${PARSE_SERVER}/api/functions`, {
-      method: 'POST',
-      headers: {
-        'Content-Type': 'application/json',
-        'X-Parse-Application-Id': PARSE_APP_ID,
-        'X-Parse-Session-Token': token,
-      },
-      body: JSON.stringify({ id: PROGRESS_FN_ID, action, sessionToken: token, _ApplicationId: PARSE_APP_ID, ...params }),
-    });
-    const json = await resp.json().catch(() => null);
-    if (!json) {
-      throw new Error('NETWORK');
-    }
-    const code = Number(json.code || resp.status);
-    if (code === 401) {
-      this.logout();
-      throw new Error('UNAUTHORIZED');
-    }
-    if (json.success === false || code >= 400) {
-      throw new Error(json.error || json.message || '请求失败');
+    const body = JSON.stringify({ id: PROGRESS_FN_ID, action, sessionToken: token, _ApplicationId: PARSE_APP_ID, ...params });
+    // FMode 云函数解析登录态时偶发空响应 / fetch failed,做有限重试以稳定看板。
+    let lastErr: Error | null = null;
+    for (let attempt = 0; attempt < 3; attempt += 1) {
+      let json: FnResponse | null = null;
+      let status = 0;
+      try {
+        const resp = await fetch(`${PARSE_SERVER}/api/functions`, {
+          method: 'POST',
+          headers: {
+            'Content-Type': 'application/json',
+            'X-Parse-Application-Id': PARSE_APP_ID,
+            'X-Parse-Session-Token': token,
+          },
+          body,
+        });
+        status = resp.status;
+        json = (await resp.json().catch(() => null)) as FnResponse | null;
+      } catch {
+        json = null;
+      }
+      const fetchFailed = json && typeof json.message === 'string' && /fetch failed/i.test(json.message);
+      if (!json || fetchFailed) {
+        lastErr = new Error('NETWORK');
+        await new Promise((resolve) => setTimeout(resolve, 600 * (attempt + 1)));
+        continue;
+      }
+      const code = Number(json.code || status);
+      if (code === 401) {
+        this.logout();
+        throw new Error('UNAUTHORIZED');
+      }
+      if (json.success === false || code >= 400) {
+        throw new Error(json.error || json.message || '请求失败');
+      }
+      return json.data as T;
     }
-    return json.data as T;
+    throw lastErr || new Error('NETWORK');
   }
 }