mirror of
https://github.com/google-gemini/gemini-cli
synced 2026-05-24 09:38:34 +00:00
Merge 524d5bb522 into 3cc7e5b096
This commit is contained in:
commit
1c154d84cb
2 changed files with 55 additions and 1 deletions
|
|
@ -1474,6 +1474,49 @@ describe('gemini.tsx main function exit codes', () => {
|
|||
|
||||
expect(refreshAuthSpy).toHaveBeenCalledWith(AuthType.USE_GEMINI);
|
||||
});
|
||||
|
||||
it('should exit with FATAL_AUTHENTICATION_ERROR when refreshAuth rejects in non-interactive mode', async () => {
|
||||
const refreshAuthSpy = vi
|
||||
.fn()
|
||||
.mockRejectedValue(new Error('ECONNRESET while listing experiments'));
|
||||
vi.mocked(loadCliConfig).mockResolvedValue(
|
||||
createMockConfig({
|
||||
isInteractive: () => false,
|
||||
getQuestion: () => 'test prompt',
|
||||
getSandbox: () => undefined,
|
||||
refreshAuth: refreshAuthSpy,
|
||||
}),
|
||||
);
|
||||
vi.mocked(validateNonInteractiveAuth).mockResolvedValue(
|
||||
AuthType.USE_GEMINI,
|
||||
);
|
||||
vi.mocked(loadSettings).mockReturnValue(
|
||||
createMockSettings({
|
||||
merged: { security: { auth: { selectedType: undefined } }, ui: {} },
|
||||
}),
|
||||
);
|
||||
vi.mocked(parseArguments).mockResolvedValue({
|
||||
enabled: true,
|
||||
allowedPaths: [],
|
||||
networkAccess: false,
|
||||
} as unknown as CliArgs);
|
||||
|
||||
runNonInteractiveSpy.mockImplementation(() => Promise.resolve());
|
||||
|
||||
vi.stubEnv('GEMINI_API_KEY', 'test-key');
|
||||
try {
|
||||
await main();
|
||||
expect.fail('Should have thrown MockProcessExitError');
|
||||
} catch (e) {
|
||||
expect(e).toBeInstanceOf(MockProcessExitError);
|
||||
expect((e as MockProcessExitError).code).toBe(
|
||||
ExitCodes.FATAL_AUTHENTICATION_ERROR,
|
||||
);
|
||||
}
|
||||
|
||||
expect(refreshAuthSpy).toHaveBeenCalledWith(AuthType.USE_GEMINI);
|
||||
expect(runNonInteractiveSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateDnsResolutionOrder', () => {
|
||||
|
|
|
|||
|
|
@ -864,7 +864,18 @@ export async function main() {
|
|||
config,
|
||||
settings,
|
||||
);
|
||||
await config.refreshAuth(authType);
|
||||
try {
|
||||
await config.refreshAuth(authType);
|
||||
} catch (err) {
|
||||
// Surface auth/network errors (e.g. ECONNRESET while fetching experiments
|
||||
// or refreshing OAuth tokens) instead of letting the rejection bubble out
|
||||
// as an unhandled crash with a raw stack trace.
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
writeToStderr(`Failed to authenticate: ${message}\n`);
|
||||
debugLogger.error('refreshAuth failed in non-interactive mode:', err);
|
||||
await runExitCleanup();
|
||||
process.exit(ExitCodes.FATAL_AUTHENTICATION_ERROR);
|
||||
}
|
||||
|
||||
if (config.getDebugMode()) {
|
||||
debugLogger.log('Session ID: %s', sessionId);
|
||||
|
|
|
|||
Loading…
Reference in a new issue