diff --git a/apps/web/app/components/chat-panel.tsx b/apps/web/app/components/chat-panel.tsx index db56d43ddcd..d58ba6c93d0 100644 --- a/apps/web/app/components/chat-panel.tsx +++ b/apps/web/app/components/chat-panel.tsx @@ -988,8 +988,11 @@ export const ChatPanel = forwardRef( status === "submitted" || isReconnecting; + const onRuntimeStateChangeRef = useRef(onRuntimeStateChange); + onRuntimeStateChangeRef.current = onRuntimeStateChange; + useEffect(() => { - onRuntimeStateChange?.({ + onRuntimeStateChangeRef.current?.({ sessionId: currentSessionId, sessionKey: subagentSessionKey ?? null, isStreaming, @@ -1004,7 +1007,6 @@ export const ChatPanel = forwardRef( status, isReconnecting, loadingSession, - onRuntimeStateChange, ]); // Stream stall detection: if we stay in "submitted" (no first diff --git a/apps/web/app/global-error.tsx b/apps/web/app/global-error.tsx new file mode 100644 index 00000000000..24f37ec9e28 --- /dev/null +++ b/apps/web/app/global-error.tsx @@ -0,0 +1,73 @@ +"use client"; + +import { useEffect } from "react"; + +function isChunkLoadError(error: Error & { name?: string }): boolean { + if (error.name === "ChunkLoadError") return true; + if (error.message?.includes("Loading chunk")) return true; + if (error.message?.includes("Loading CSS chunk")) return true; + return false; +} + +export default function GlobalError({ + error, + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + useEffect(() => { + if (isChunkLoadError(error)) { + const key = "__chunk_reload"; + if (!sessionStorage.getItem(key)) { + sessionStorage.setItem(key, "1"); + window.location.reload(); + return; + } + sessionStorage.removeItem(key); + } + }, [error]); + + return ( + + +
+

+ {isChunkLoadError(error) + ? "A new version is available" + : "Something went wrong"} +

+

+ {isChunkLoadError(error) + ? "The app was updated while you had it open. Reload to get the latest version." + : "An unexpected error occurred. Try reloading the page."} +

+ +
+ + + ); +} diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 0f6377320fd..11729bbcaeb 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -31,6 +31,25 @@ export default function RootLayout({ return ( +