fix(cli): clear static error message when starting new query

Previously, only countdown-based errors were cleared when user starts
a new query. Static errors (like "Press Ctrl+Y to retry") remained
visible. Now both types of errors are properly cleared.
This commit is contained in:
yiliang114 2026-03-05 16:00:58 +08:00
parent 991ae9febc
commit 8ad4a2d205
2 changed files with 81 additions and 3 deletions

View file

@ -2526,6 +2526,77 @@ describe('useGeminiStream', () => {
expect.any(String),
);
});
it('should clear static error when starting a new query', async () => {
// First, mock a stream that yields an error (static error without countdown)
mockSendMessageStream.mockReturnValueOnce(
(async function* () {
yield {
type: ServerGeminiEventType.Error,
value: { error: { message: 'First error' } },
};
})(),
);
const { result } = renderHook(() =>
useGeminiStream(
new MockedGeminiClientClass(mockConfig),
[],
mockAddItem,
mockConfig,
mockLoadedSettings,
mockOnDebugMessage,
mockHandleSlashCommand,
false,
() => 'vscode' as EditorType,
() => {},
() => Promise.resolve(),
false,
() => {},
() => {},
() => {},
() => {},
80,
24,
),
);
// Submit first query that will fail
await act(async () => {
await result.current.submitQuery('First query');
});
// Verify error appears in pending history items
await waitFor(() => {
const errorItem = result.current.pendingHistoryItems.find(
(item) => item.type === 'error',
);
expect(errorItem).toBeDefined();
});
// Now mock a successful stream for the second query
mockSendMessageStream.mockReturnValueOnce(
(async function* () {
yield {
type: ServerGeminiEventType.Text,
value: 'Success response',
};
})(),
);
// Submit second query
await act(async () => {
await result.current.submitQuery('Second query');
});
// Verify the error is cleared (no longer in pending history items)
await waitFor(() => {
const errorItem = result.current.pendingHistoryItems.find(
(item) => item.type === 'error',
);
expect(errorItem).toBeUndefined();
});
});
});
describe('Concurrent Execution Prevention', () => {

View file

@ -1080,8 +1080,13 @@ export const useGeminiStream = (
if (!options?.isContinuation) {
setModelSwitchedFromQuotaError(false);
// Commit any pending retry error to history (without hint) since the
// user is starting a new conversation turn
if (pendingRetryCountdownItemRef.current) {
// user is starting a new conversation turn.
// Clear both countdown-based errors AND static errors (those without
// an active countdown timer, e.g. "Press Ctrl+Y to retry").
if (
pendingRetryCountdownItemRef.current ||
pendingRetryErrorItemRef.current
) {
clearRetryCountdown();
}
}
@ -1176,7 +1181,8 @@ export const useGeminiStream = (
}
// Only clear auto-retry countdown errors (those with an active timer).
// Do NOT clear static error+hint from handleErrorEvent — those should
// remain visible until the user presses Ctrl+Y to retry.
// remain visible until the user presses Ctrl+Y to retry or starts
// a new conversation turn (cleared in submitQuery).
if (retryCountdownTimerRef.current) {
clearRetryCountdown();
}
@ -1223,6 +1229,7 @@ export const useGeminiStream = (
handleLoopDetectedEvent,
clearRetryCountdown,
pendingRetryCountdownItemRef,
pendingRetryErrorItemRef,
setPendingRetryErrorItem,
],
);