opt(chat): Enhance error handling for chat.send timeouts and improve logging in gateway RPC calls (#788)
This commit is contained in:
@@ -1152,6 +1152,7 @@ function registerGatewayHandlers(
|
|||||||
const result = await gatewayManager.rpc(method, params, timeoutMs);
|
const result = await gatewayManager.rpc(method, params, timeoutMs);
|
||||||
return { success: true, result };
|
return { success: true, result };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
logger.warn(`[gateway:rpc] ${method} failed (timeoutMs=${timeoutMs ?? 30000}): ${String(error)}`);
|
||||||
return { success: false, error: String(error) };
|
return { success: false, error: String(error) };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -956,6 +956,15 @@ function upsertToolStatuses(current: ToolStatus[], updates: ToolStatus[]): ToolS
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only treat an explicit chat.send ack timeout as recoverable.
|
||||||
|
* Gateway stopped / Gateway not connected are hard failures that
|
||||||
|
* should still terminate the send immediately.
|
||||||
|
*/
|
||||||
|
function isRecoverableChatSendTimeout(error: string): boolean {
|
||||||
|
return error.includes('RPC timeout: chat.send');
|
||||||
|
}
|
||||||
|
|
||||||
function collectToolUpdates(message: unknown, eventState: string): ToolStatus[] {
|
function collectToolUpdates(message: unknown, eventState: string): ToolStatus[] {
|
||||||
const updates: ToolStatus[] = [];
|
const updates: ToolStatus[] = [];
|
||||||
const toolResultUpdate = extractToolResultUpdate(message, eventState);
|
const toolResultUpdate = extractToolResultUpdate(message, eventState);
|
||||||
@@ -1675,14 +1684,26 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|||||||
console.log(`[sendMessage] RPC result: success=${result.success}, runId=${result.result?.runId || 'none'}`);
|
console.log(`[sendMessage] RPC result: success=${result.success}, runId=${result.result?.runId || 'none'}`);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
|
const errorMsg = result.error || 'Failed to send message';
|
||||||
|
if (isRecoverableChatSendTimeout(errorMsg)) {
|
||||||
|
console.warn(`[sendMessage] Recoverable chat.send timeout, keeping poll alive: ${errorMsg}`);
|
||||||
|
set({ error: errorMsg });
|
||||||
|
} else {
|
||||||
clearHistoryPoll();
|
clearHistoryPoll();
|
||||||
set({ error: result.error || 'Failed to send message', sending: false });
|
set({ error: errorMsg, sending: false });
|
||||||
|
}
|
||||||
} else if (result.result?.runId) {
|
} else if (result.result?.runId) {
|
||||||
set({ activeRunId: result.result.runId });
|
set({ activeRunId: result.result.runId });
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
const errStr = String(err);
|
||||||
|
if (isRecoverableChatSendTimeout(errStr)) {
|
||||||
|
console.warn(`[sendMessage] Recoverable chat.send timeout, keeping poll alive: ${errStr}`);
|
||||||
|
set({ error: errStr });
|
||||||
|
} else {
|
||||||
clearHistoryPoll();
|
clearHistoryPoll();
|
||||||
set({ error: String(err), sending: false });
|
set({ error: errStr, sending: false });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1761,11 +1782,11 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'delta': {
|
case 'delta': {
|
||||||
// If we're receiving new deltas, the Gateway has recovered from any
|
// Clear any stale error (including RPC timeout) when new data arrives.
|
||||||
// prior error — cancel the error finalization timer and clear the
|
|
||||||
// stale error banner so the user sees the live stream again.
|
|
||||||
if (_errorRecoveryTimer) {
|
if (_errorRecoveryTimer) {
|
||||||
clearErrorRecoveryTimer();
|
clearErrorRecoveryTimer();
|
||||||
|
}
|
||||||
|
if (get().error) {
|
||||||
set({ error: null });
|
set({ error: null });
|
||||||
}
|
}
|
||||||
const updates = collectToolUpdates(event.message, resolvedState);
|
const updates = collectToolUpdates(event.message, resolvedState);
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ function handleGatewayNotification(notification: { method?: string; params?: Rec
|
|||||||
activeRunId: null,
|
activeRunId: null,
|
||||||
pendingFinal: false,
|
pendingFinal: false,
|
||||||
lastUserMessageAt: null,
|
lastUserMessageAt: null,
|
||||||
|
error: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user