fix(ai): 网络失败时显示友好提示,不再直接展示 Failed to fetch

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
fucheng
2026-09-20 09:59:35 +08:00
parent b008307f82
commit 99052ada5f
11 changed files with 92 additions and 21 deletions
+33
View File
@@ -0,0 +1,33 @@
/** Browser / WebView fetch failures are usually TypeError with an opaque message. */
export const AI_NETWORK_ERROR_CODE = "AI_UNREACHABLE";
const NETWORK_FETCH_HINTS = [
"failed to fetch",
"networkerror",
"network request failed",
"load failed",
"internet connection appears to be offline",
];
export function isLikelyNetworkFetchError(error: unknown): boolean {
const name = error instanceof Error ? error.name : "";
const msg = (error instanceof Error ? error.message : String(error ?? "")).toLowerCase();
if (msg === AI_NETWORK_ERROR_CODE.toLowerCase()) return true;
if (NETWORK_FETCH_HINTS.some((hint) => msg.includes(hint))) return true;
// Some WebViews surface a bare TypeError when fetch cannot complete.
return name === "TypeError" && !msg;
}
export function formatNetworkAwareMessage(
template: string,
error: unknown,
networkCopy: string,
): string {
const raw = error instanceof Error ? error.message : String(error ?? "");
const message = isLikelyNetworkFetchError(error) || isLikelyNetworkFetchError(raw) ? networkCopy : raw;
if (template.includes("{message}")) {
return template.split("{message}").join(String(message));
}
return isLikelyNetworkFetchError(error) || isLikelyNetworkFetchError(raw) ? networkCopy : template;
}