fix(ai): 网络失败时显示友好提示,不再直接展示 Failed to fetch
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+15
-2
@@ -11,6 +11,7 @@ import {
|
||||
dbToVolume,
|
||||
volumeToDb,
|
||||
} from "./luxsinApi";
|
||||
import { AI_NETWORK_ERROR_CODE, isLikelyNetworkFetchError } from "./networkError";
|
||||
|
||||
// Allow override via Vite env / localStorage; default to same origin in prod.
|
||||
export function getAIBaseUrl(): string {
|
||||
@@ -120,7 +121,13 @@ export interface QuestionPayload {
|
||||
// REST helpers
|
||||
// ============================================================
|
||||
async function jsonFetch<T>(url: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(url, init);
|
||||
let res: Response;
|
||||
try {
|
||||
res = await fetch(url, init);
|
||||
} catch (error) {
|
||||
if (isLikelyNetworkFetchError(error)) throw new Error(AI_NETWORK_ERROR_CODE);
|
||||
throw error;
|
||||
}
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
|
||||
return res.json();
|
||||
}
|
||||
@@ -293,7 +300,7 @@ export function streamQuestion(payload: QuestionPayload, cb: StreamCallbacks): A
|
||||
cb.onDone?.();
|
||||
} catch (e: any) {
|
||||
if (e?.name === "AbortError") return;
|
||||
cb.onError?.(e?.message ?? String(e));
|
||||
cb.onError?.(isLikelyNetworkFetchError(e) ? AI_NETWORK_ERROR_CODE : (e?.message ?? String(e)));
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -472,6 +479,12 @@ export async function executeFrontendTool(
|
||||
return { ok: false, message: `Unsupported tool: ${block.name}` };
|
||||
}
|
||||
} catch (e: any) {
|
||||
if (isLikelyNetworkFetchError(e)) {
|
||||
return {
|
||||
ok: false,
|
||||
message: "Device is not reachable. Ask the user to reconnect the device on the same network, then retry.",
|
||||
};
|
||||
}
|
||||
return { ok: false, message: e?.message ?? String(e) };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user