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);
|
||||
return { success: true, result };
|
||||
} catch (error) {
|
||||
logger.warn(`[gateway:rpc] ${method} failed (timeoutMs=${timeoutMs ?? 30000}): ${String(error)}`);
|
||||
return { success: false, error: String(error) };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -956,6 +956,15 @@ function upsertToolStatuses(current: ToolStatus[], updates: ToolStatus[]): ToolS
|
||||
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[] {
|
||||
const updates: ToolStatus[] = [];
|
||||
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'}`);
|
||||
|
||||
if (!result.success) {
|
||||
clearHistoryPoll();
|
||||
set({ error: result.error || 'Failed to send message', sending: false });
|
||||
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();
|
||||
set({ error: errorMsg, sending: false });
|
||||
}
|
||||
} else if (result.result?.runId) {
|
||||
set({ activeRunId: result.result.runId });
|
||||
}
|
||||
} catch (err) {
|
||||
clearHistoryPoll();
|
||||
set({ error: String(err), sending: false });
|
||||
const errStr = String(err);
|
||||
if (isRecoverableChatSendTimeout(errStr)) {
|
||||
console.warn(`[sendMessage] Recoverable chat.send timeout, keeping poll alive: ${errStr}`);
|
||||
set({ error: errStr });
|
||||
} else {
|
||||
clearHistoryPoll();
|
||||
set({ error: errStr, sending: false });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1761,11 +1782,11 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
||||
break;
|
||||
}
|
||||
case 'delta': {
|
||||
// If we're receiving new deltas, the Gateway has recovered from any
|
||||
// prior error — cancel the error finalization timer and clear the
|
||||
// stale error banner so the user sees the live stream again.
|
||||
// Clear any stale error (including RPC timeout) when new data arrives.
|
||||
if (_errorRecoveryTimer) {
|
||||
clearErrorRecoveryTimer();
|
||||
}
|
||||
if (get().error) {
|
||||
set({ error: null });
|
||||
}
|
||||
const updates = collectToolUpdates(event.message, resolvedState);
|
||||
|
||||
@@ -177,6 +177,7 @@ function handleGatewayNotification(notification: { method?: string; params?: Rec
|
||||
activeRunId: null,
|
||||
pendingFinal: false,
|
||||
lastUserMessageAt: null,
|
||||
error: null,
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user