feat(FN-3608): update dashboard chat documentation
Updated the dashboard chat documentation in the user guide with a minor addition. Fusion-Task-Id: FN-3608
This commit is contained in:
10
.changeset/chat-stream-stuck-state.md
Normal file
10
.changeset/chat-stream-stuck-state.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix chat sending silently failing on flaky networks (especially mobile).
|
||||||
|
The SSE reader in the dashboard client now treats a closed stream without
|
||||||
|
a terminal `done`/`error` event as an error so streaming state unwinds
|
||||||
|
instead of getting stuck. The `useChat` and `useQuickChat` hooks also now
|
||||||
|
show a toast when a message is queued behind an in-flight response, so
|
||||||
|
the previous stuck state is observable rather than silent.
|
||||||
@@ -8058,6 +8058,7 @@ export function streamChatResponse(
|
|||||||
|
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
let closedByUser = false;
|
let closedByUser = false;
|
||||||
|
let terminated = false;
|
||||||
|
|
||||||
const dispatchEvent = (eventName: string, rawData: string): void => {
|
const dispatchEvent = (eventName: string, rawData: string): void => {
|
||||||
if (!eventName) {
|
if (!eventName) {
|
||||||
@@ -8101,6 +8102,7 @@ export function streamChatResponse(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "done":
|
case "done":
|
||||||
|
terminated = true;
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(rawData) as { messageId?: unknown; message?: unknown };
|
const parsed = JSON.parse(rawData) as { messageId?: unknown; message?: unknown };
|
||||||
handlers.onDone?.({
|
handlers.onDone?.({
|
||||||
@@ -8112,6 +8114,7 @@ export function streamChatResponse(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
|
terminated = true;
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(rawData);
|
const parsed = JSON.parse(rawData);
|
||||||
handlers.onError?.(parsed.message || parsed);
|
handlers.onError?.(parsed.message || parsed);
|
||||||
@@ -8216,6 +8219,14 @@ export function streamChatResponse(
|
|||||||
|
|
||||||
processLines(decoder.decode(value, { stream: true }));
|
processLines(decoder.decode(value, { stream: true }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Server closed the stream without emitting a terminal `done` or `error`
|
||||||
|
// SSE event (common on flaky mobile networks, proxy idle-kill, or
|
||||||
|
// backgrounded tabs). Surface as an error so the client unwinds
|
||||||
|
// streaming state instead of getting stuck with isStreaming=true.
|
||||||
|
if (!terminated && !closedByUser) {
|
||||||
|
handlers.onError?.("Connection closed unexpectedly");
|
||||||
|
}
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (err instanceof DOMException && err.name === "AbortError") {
|
if (err instanceof DOMException && err.name === "AbortError") {
|
||||||
if (!closedByUser) {
|
if (!closedByUser) {
|
||||||
|
|||||||
@@ -492,6 +492,7 @@ export function useChat(
|
|||||||
if (isStreaming) {
|
if (isStreaming) {
|
||||||
pendingMessageRef.current = content;
|
pendingMessageRef.current = content;
|
||||||
setPendingMessage(content);
|
setPendingMessage(content);
|
||||||
|
addToast?.("Still waiting for previous response — message queued", "warning");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -557,6 +557,7 @@ export function useQuickChat(
|
|||||||
|
|
||||||
pendingMessageRef.current = content;
|
pendingMessageRef.current = content;
|
||||||
setPendingMessage(content);
|
setPendingMessage(content);
|
||||||
|
addToast?.("Still waiting for previous response — message queued", "warning");
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user