Fix for silent failures in non-interactive mode (#19905)

This commit is contained in:
owenofbrien
2026-02-23 11:35:13 -06:00
committed by GitHub
parent 6628cbb39d
commit fa9aee2bf0
4 changed files with 27 additions and 7 deletions

View File

@@ -13,6 +13,7 @@ import {
getAllMCPServerStatuses,
MCPServerStatus,
isNodeError,
getErrorMessage,
parseAndFormatApiError,
safeLiteralReplace,
DEFAULT_GUI_EDITOR,
@@ -727,16 +728,17 @@ export class Task {
// Block scope for lexical declaration
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const errorEvent = event as ServerGeminiErrorEvent; // Type assertion
const errorMessage =
errorEvent.value?.error.message ?? 'Unknown error from LLM stream';
const errorMessage = errorEvent.value?.error
? getErrorMessage(errorEvent.value.error)
: 'Unknown error from LLM stream';
logger.error(
'[Task] Received error event from LLM stream:',
errorMessage,
);
let errMessage = `Unknown error from LLM stream: ${JSON.stringify(event)}`;
if (errorEvent.value) {
errMessage = parseAndFormatApiError(errorEvent.value);
if (errorEvent.value?.error) {
errMessage = parseAndFormatApiError(errorEvent.value.error);
}
this.cancelPendingTools(`LLM stream error: ${errorMessage}`);
this.setTaskStateAndPublishUpdate(

View File

@@ -36,7 +36,21 @@ process.on('uncaughtException', (error) => {
});
main().catch(async (error) => {
await runExitCleanup();
// Set a timeout to force exit if cleanup hangs
const cleanupTimeout = setTimeout(() => {
writeToStderr('Cleanup timed out, forcing exit...\n');
process.exit(1);
}, 5000);
try {
await runExitCleanup();
} catch (cleanupError) {
writeToStderr(
`Error during final cleanup: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}\n`,
);
} finally {
clearTimeout(cleanupTimeout);
}
if (error instanceof FatalError) {
let errorMessage = error.message;
@@ -46,6 +60,7 @@ main().catch(async (error) => {
writeToStderr(errorMessage + '\n');
process.exit(error.exitCode);
}
writeToStderr('An unexpected critical error occurred:');
if (error instanceof Error) {
writeToStderr(error.stack + '\n');

View File

@@ -261,7 +261,10 @@ describe('Turn', () => {
const errorEvent = events[0] as ServerGeminiErrorEvent;
expect(errorEvent.type).toBe(GeminiEventType.Error);
expect(errorEvent.value).toEqual({
error: { message: 'API Error', status: undefined },
error: {
message: 'API Error',
status: undefined,
},
});
expect(turn.getDebugResponses().length).toBe(0);
expect(reportError).toHaveBeenCalledWith(

View File

@@ -116,7 +116,7 @@ export interface StructuredError {
}
export interface GeminiErrorEventValue {
error: StructuredError;
error: unknown;
}
export interface GeminiFinishedEventValue {