R65 A1-A6:Session 稳定性与 409 资源错误修复
这个提交包含在:
+97
-1
@@ -7,9 +7,105 @@ import { ErrorBoundary } from "./components/common/ErrorBoundary";
|
||||
import { Toaster } from "./components/ui/sonner";
|
||||
import { queryClient } from "./query/queryClient";
|
||||
import { AppRouter } from "./router";
|
||||
import { registerPwaIfEnabled } from "./pwa";
|
||||
import { clearPwaRuntimeCaches, registerPwaIfEnabled } from "./pwa";
|
||||
import "./index.css";
|
||||
|
||||
const CHUNK_RELOAD_ATTEMPTED_KEY = "hyb_oa_chunk_reload_attempted";
|
||||
const CHUNK_LOAD_ERROR_PATTERNS = [
|
||||
"chunkloaderror",
|
||||
"loading chunk",
|
||||
"failed to fetch dynamically imported module",
|
||||
"importing a module script failed",
|
||||
"error loading dynamically imported module",
|
||||
];
|
||||
|
||||
function extractErrorMessages(value: unknown): string[] {
|
||||
if (!value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (typeof value === "string") {
|
||||
return [value];
|
||||
}
|
||||
|
||||
if (value instanceof Error) {
|
||||
return [value.name, value.message];
|
||||
}
|
||||
|
||||
if (typeof value !== "object") {
|
||||
return [];
|
||||
}
|
||||
|
||||
const record = value as {
|
||||
message?: unknown;
|
||||
reason?: unknown;
|
||||
payload?: unknown;
|
||||
error?: unknown;
|
||||
};
|
||||
|
||||
return [
|
||||
...extractErrorMessages(record.message),
|
||||
...extractErrorMessages(record.reason),
|
||||
...extractErrorMessages(record.payload),
|
||||
...extractErrorMessages(record.error),
|
||||
];
|
||||
}
|
||||
|
||||
function isChunkLoadFailure(value: unknown) {
|
||||
return extractErrorMessages(value).some((message) => {
|
||||
const normalized = message.toLowerCase();
|
||||
return CHUNK_LOAD_ERROR_PATTERNS.some((pattern) => normalized.includes(pattern));
|
||||
});
|
||||
}
|
||||
|
||||
function installChunkLoadRecovery() {
|
||||
if (typeof window === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
let reloadTriggered = false;
|
||||
const reloadForChunkFailure = () => {
|
||||
if (reloadTriggered || window.sessionStorage.getItem(CHUNK_RELOAD_ATTEMPTED_KEY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
reloadTriggered = true;
|
||||
window.sessionStorage.setItem(CHUNK_RELOAD_ATTEMPTED_KEY, "1");
|
||||
void clearPwaRuntimeCaches()
|
||||
.catch(() => undefined)
|
||||
.finally(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
};
|
||||
|
||||
window.addEventListener("vite:preloadError", (event) => {
|
||||
if (!isChunkLoadFailure(event.payload)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
reloadForChunkFailure();
|
||||
});
|
||||
|
||||
window.addEventListener("error", (event) => {
|
||||
if (!isChunkLoadFailure(event.error ?? event.message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
reloadForChunkFailure();
|
||||
});
|
||||
|
||||
window.addEventListener("unhandledrejection", (event) => {
|
||||
if (!isChunkLoadFailure(event.reason)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
reloadForChunkFailure();
|
||||
});
|
||||
}
|
||||
|
||||
installChunkLoadRecovery();
|
||||
registerPwaIfEnabled();
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||
|
||||
在新工单中引用
屏蔽一个用户