fix(threads): 忽略流取消导致的错误提示
识别 cancelled/canceled/abort 等取消信号。\n在流式请求被主动停止或中断时不再弹出错误 toast,减少误报。
This commit is contained in:
parent
22f616ab2a
commit
5823fbfa72
|
|
@ -43,7 +43,7 @@ export function WorkspaceHeader({ className }: { className?: string }) {
|
|||
) : (
|
||||
<div className="text-primary ml-2 cursor-default font-serif">
|
||||
{/* TODO: 测试标识 */}
|
||||
XClaw <span className="text-sm text-[#000000c5]">v3.2.3</span>
|
||||
XClaw <span className="text-sm text-[#000000c5]">v3.2.4</span>
|
||||
</div>
|
||||
)}
|
||||
<SidebarTrigger />
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ export type LegacyThreadStreamOptions = {
|
|||
const STREAM_ERROR_FALLBACK_MESSAGE = "Request failed.";
|
||||
const STREAM_ERROR_TOAST_MESSAGE = "出现了某些错误。";
|
||||
const STREAM_ERROR_TOAST_DEDUPE_WINDOW_MS = 2000;
|
||||
const STREAM_CANCEL_PATTERNS = [
|
||||
/\bcancellederror\b/i,
|
||||
/\bcancelled\b/i,
|
||||
/\bcanceled\b/i,
|
||||
/\babort(?:ed|error)?\b/i,
|
||||
];
|
||||
|
||||
function readMessageCandidate(value: unknown): string | null {
|
||||
if (typeof value === "string" && value.trim()) {
|
||||
|
|
@ -116,6 +122,21 @@ function getStreamErrorMessage(error: unknown): string {
|
|||
return STREAM_ERROR_FALLBACK_MESSAGE;
|
||||
}
|
||||
|
||||
function isStreamCancellation(error: unknown, message: string): boolean {
|
||||
const direct =
|
||||
typeof error === "object" &&
|
||||
error !== null &&
|
||||
"name" in error &&
|
||||
typeof Reflect.get(error, "name") === "string"
|
||||
? String(Reflect.get(error, "name"))
|
||||
: "";
|
||||
|
||||
const candidates = [message, direct];
|
||||
return candidates.some((value) =>
|
||||
STREAM_CANCEL_PATTERNS.some((pattern) => pattern.test(value)),
|
||||
);
|
||||
}
|
||||
|
||||
function normalizeThreadId(
|
||||
value: string | null | undefined,
|
||||
): string | undefined {
|
||||
|
|
@ -234,6 +255,11 @@ export function useThreadStream({
|
|||
|
||||
const showStreamErrorToast = useCallback((error: unknown) => {
|
||||
const message = getStreamErrorMessage(error);
|
||||
if (isStreamCancellation(error, message)) {
|
||||
// Cancellation is expected when user presses "Stop" or stream disconnects.
|
||||
console.info("[useThreadStream] stream cancelled:", message);
|
||||
return;
|
||||
}
|
||||
const now = Date.now();
|
||||
const lastToast = lastErrorToastRef.current;
|
||||
if (
|
||||
|
|
|
|||
Loading…
Reference in New Issue