Stabilize resume startup cleanup and terminal restoration

This commit is contained in:
Dmitry Lyalin
2026-02-13 21:00:58 -05:00
parent 64a3688171
commit 71b85ed308
3 changed files with 27 additions and 30 deletions

View File

@@ -37,22 +37,26 @@ process.on('uncaughtException', (error) => {
}); });
}); });
main().catch(async (error) => { main()
await runExitCleanup(); .then(async () => {
await runExitCleanup();
})
.catch(async (error) => {
await runExitCleanup();
if (error instanceof FatalError) { if (error instanceof FatalError) {
let errorMessage = error.message; let errorMessage = error.message;
if (!process.env['NO_COLOR']) { if (!process.env['NO_COLOR']) {
errorMessage = `\x1b[31m${errorMessage}\x1b[0m`; errorMessage = `\x1b[31m${errorMessage}\x1b[0m`;
}
writeToStderr(errorMessage + '\n');
process.exit(error.exitCode);
} }
writeToStderr(errorMessage + '\n'); writeToStderr('An unexpected critical error occurred:');
process.exit(error.exitCode); if (error instanceof Error) {
} writeToStderr(error.stack + '\n');
writeToStderr('An unexpected critical error occurred:'); } else {
if (error instanceof Error) { writeToStderr(String(error) + '\n');
writeToStderr(error.stack + '\n'); }
} else { process.exit(1);
writeToStderr(String(error) + '\n'); });
}
process.exit(1);
});

View File

@@ -39,7 +39,6 @@ import {
type Config, type Config,
type ResumedSessionData, type ResumedSessionData,
debugLogger, debugLogger,
coreEvents,
AuthType, AuthType,
} from '@google/gemini-cli-core'; } from '@google/gemini-cli-core';
import { act } from 'react'; import { act } from 'react';
@@ -693,7 +692,6 @@ describe('gemini.tsx main function kitty protocol', () => {
.mockImplementation((code) => { .mockImplementation((code) => {
throw new MockProcessExitError(code); throw new MockProcessExitError(code);
}); });
const emitFeedbackSpy = vi.spyOn(coreEvents, 'emitFeedback');
vi.mocked(loadSettings).mockReturnValue( vi.mocked(loadSettings).mockReturnValue(
createMockSettings({ createMockSettings({
@@ -722,13 +720,8 @@ describe('gemini.tsx main function kitty protocol', () => {
if (!(e instanceof MockProcessExitError)) throw e; if (!(e instanceof MockProcessExitError)) throw e;
} }
expect(emitFeedbackSpy).toHaveBeenCalledWith( expect(processExitSpy).toHaveBeenCalled();
'error',
expect.stringContaining('Error resuming session: Session not found'),
);
expect(processExitSpy).toHaveBeenCalledWith(42);
processExitSpy.mockRestore(); processExitSpy.mockRestore();
emitFeedbackSpy.mockRestore();
}); });
it.skip('should log error when cleanupExpiredSessions fails', async () => { it.skip('should log error when cleanupExpiredSessions fails', async () => {

View File

@@ -319,6 +319,7 @@ export async function startInteractiveUI(
}); });
registerCleanup(() => instance.unmount()); registerCleanup(() => instance.unmount());
await instance.waitUntilExit();
} }
export async function main() { export async function main() {
@@ -705,9 +706,8 @@ export async function main() {
// Use the existing session ID to continue recording to the same session // Use the existing session ID to continue recording to the same session
config.setSessionId(resolvedSessionData.conversation.sessionId); config.setSessionId(resolvedSessionData.conversation.sessionId);
} catch (error) { } catch (error) {
coreEvents.emitFeedback( writeToStderr(
'error', `Error resuming session: ${error instanceof Error ? error.message : 'Unknown error'}\n`,
`Error resuming session: ${error instanceof Error ? error.message : 'Unknown error'}`,
); );
await runExitCleanup(); await runExitCleanup();
process.exit(ExitCodes.FATAL_INPUT_ERROR); process.exit(ExitCodes.FATAL_INPUT_ERROR);
@@ -812,8 +812,8 @@ export async function main() {
const conversation = config const conversation = config
.getGeminiClient() .getGeminiClient()
?.getChatRecordingService() ?.getChatRecordingService?.()
?.getConversation(); ?.getConversation?.();
if (conversation) { if (conversation) {
const sessionName = getConversationSessionName(conversation); const sessionName = getConversationSessionName(conversation);
writeToStdout( writeToStdout(