mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-13 07:30:52 -07:00
Update error codes when process exiting the gemini cli (#13728)
This commit is contained in:
@@ -20,6 +20,7 @@ import {
|
||||
OutputFormat,
|
||||
makeFakeConfig,
|
||||
debugLogger,
|
||||
ExitCodes,
|
||||
} from '@google/gemini-cli-core';
|
||||
import type { Config } from '@google/gemini-cli-core';
|
||||
import * as auth from './config/auth.js';
|
||||
@@ -116,12 +117,16 @@ describe('validateNonInterActiveAuth', () => {
|
||||
);
|
||||
expect.fail('Should have exited');
|
||||
} catch (e) {
|
||||
expect((e as Error).message).toContain('process.exit(1) called');
|
||||
expect((e as Error).message).toContain(
|
||||
`process.exit(${ExitCodes.FATAL_AUTHENTICATION_ERROR}) called`,
|
||||
);
|
||||
}
|
||||
expect(debugLoggerErrorSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining('Please set an Auth method'),
|
||||
);
|
||||
expect(processExitSpy).toHaveBeenCalledWith(1);
|
||||
expect(processExitSpy).toHaveBeenCalledWith(
|
||||
ExitCodes.FATAL_AUTHENTICATION_ERROR,
|
||||
);
|
||||
});
|
||||
|
||||
it('uses LOGIN_WITH_GOOGLE if GOOGLE_GENAI_USE_GCA is set', async () => {
|
||||
@@ -268,10 +273,14 @@ describe('validateNonInterActiveAuth', () => {
|
||||
);
|
||||
expect.fail('Should have exited');
|
||||
} catch (e) {
|
||||
expect((e as Error).message).toContain('process.exit(1) called');
|
||||
expect((e as Error).message).toContain(
|
||||
`process.exit(${ExitCodes.FATAL_AUTHENTICATION_ERROR}) called`,
|
||||
);
|
||||
}
|
||||
expect(debugLoggerErrorSpy).toHaveBeenCalledWith('Auth error!');
|
||||
expect(processExitSpy).toHaveBeenCalledWith(1);
|
||||
expect(processExitSpy).toHaveBeenCalledWith(
|
||||
ExitCodes.FATAL_AUTHENTICATION_ERROR,
|
||||
);
|
||||
});
|
||||
|
||||
it('skips validation if useExternalAuth is true', async () => {
|
||||
@@ -329,12 +338,16 @@ describe('validateNonInterActiveAuth', () => {
|
||||
);
|
||||
expect.fail('Should have exited');
|
||||
} catch (e) {
|
||||
expect((e as Error).message).toContain('process.exit(1) called');
|
||||
expect((e as Error).message).toContain(
|
||||
`process.exit(${ExitCodes.FATAL_AUTHENTICATION_ERROR}) called`,
|
||||
);
|
||||
}
|
||||
expect(debugLoggerErrorSpy).toHaveBeenCalledWith(
|
||||
"The enforced authentication type is 'oauth-personal', but the current type is 'gemini-api-key'. Please re-authenticate with the correct type.",
|
||||
);
|
||||
expect(processExitSpy).toHaveBeenCalledWith(1);
|
||||
expect(processExitSpy).toHaveBeenCalledWith(
|
||||
ExitCodes.FATAL_AUTHENTICATION_ERROR,
|
||||
);
|
||||
});
|
||||
|
||||
it('exits if auth from env var does not match enforcedAuthType', async () => {
|
||||
@@ -354,16 +367,20 @@ describe('validateNonInterActiveAuth', () => {
|
||||
);
|
||||
expect.fail('Should have exited');
|
||||
} catch (e) {
|
||||
expect((e as Error).message).toContain('process.exit(1) called');
|
||||
expect((e as Error).message).toContain(
|
||||
`process.exit(${ExitCodes.FATAL_AUTHENTICATION_ERROR}) called`,
|
||||
);
|
||||
}
|
||||
expect(debugLoggerErrorSpy).toHaveBeenCalledWith(
|
||||
"The enforced authentication type is 'oauth-personal', but the current type is 'gemini-api-key'. Please re-authenticate with the correct type.",
|
||||
);
|
||||
expect(processExitSpy).toHaveBeenCalledWith(1);
|
||||
expect(processExitSpy).toHaveBeenCalledWith(
|
||||
ExitCodes.FATAL_AUTHENTICATION_ERROR,
|
||||
);
|
||||
});
|
||||
|
||||
describe('JSON output mode', () => {
|
||||
it('prints JSON error when no auth is configured and exits with code 1', async () => {
|
||||
it(`prints JSON error when no auth is configured and exits with code ${ExitCodes.FATAL_AUTHENTICATION_ERROR}`, async () => {
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
getOutputFormat: vi.fn().mockReturnValue(OutputFormat.JSON),
|
||||
@@ -384,17 +401,19 @@ describe('validateNonInterActiveAuth', () => {
|
||||
thrown = e as Error;
|
||||
}
|
||||
|
||||
expect(thrown?.message).toBe('process.exit(1) called');
|
||||
expect(thrown?.message).toBe(
|
||||
`process.exit(${ExitCodes.FATAL_AUTHENTICATION_ERROR}) called`,
|
||||
);
|
||||
const errorArg = consoleErrorSpy.mock.calls[0]?.[0] as string;
|
||||
const payload = JSON.parse(errorArg);
|
||||
expect(payload.error.type).toBe('Error');
|
||||
expect(payload.error.code).toBe(1);
|
||||
expect(payload.error.code).toBe(ExitCodes.FATAL_AUTHENTICATION_ERROR);
|
||||
expect(payload.error.message).toContain(
|
||||
'Please set an Auth method in your',
|
||||
);
|
||||
});
|
||||
|
||||
it('prints JSON error when enforced auth mismatches current auth and exits with code 1', async () => {
|
||||
it(`prints JSON error when enforced auth mismatches current auth and exits with code ${ExitCodes.FATAL_AUTHENTICATION_ERROR}`, async () => {
|
||||
mockSettings.merged.security!.auth!.enforcedType = AuthType.USE_GEMINI;
|
||||
const nonInteractiveConfig = createLocalMockConfig({
|
||||
refreshAuth: refreshAuthMock,
|
||||
@@ -416,19 +435,21 @@ describe('validateNonInterActiveAuth', () => {
|
||||
thrown = e as Error;
|
||||
}
|
||||
|
||||
expect(thrown?.message).toBe('process.exit(1) called');
|
||||
expect(thrown?.message).toBe(
|
||||
`process.exit(${ExitCodes.FATAL_AUTHENTICATION_ERROR}) called`,
|
||||
);
|
||||
{
|
||||
const errorArg = consoleErrorSpy.mock.calls[0]?.[0] as string;
|
||||
const payload = JSON.parse(errorArg);
|
||||
expect(payload.error.type).toBe('Error');
|
||||
expect(payload.error.code).toBe(1);
|
||||
expect(payload.error.code).toBe(ExitCodes.FATAL_AUTHENTICATION_ERROR);
|
||||
expect(payload.error.message).toContain(
|
||||
"The enforced authentication type is 'gemini-api-key', but the current type is 'oauth-personal'. Please re-authenticate with the correct type.",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('prints JSON error when validateAuthMethod fails and exits with code 1', async () => {
|
||||
it(`prints JSON error when validateAuthMethod fails and exits with code ${ExitCodes.FATAL_AUTHENTICATION_ERROR}`, async () => {
|
||||
vi.spyOn(auth, 'validateAuthMethod').mockReturnValue('Auth error!');
|
||||
process.env['GEMINI_API_KEY'] = 'fake-key';
|
||||
|
||||
@@ -452,12 +473,14 @@ describe('validateNonInterActiveAuth', () => {
|
||||
thrown = e as Error;
|
||||
}
|
||||
|
||||
expect(thrown?.message).toBe('process.exit(1) called');
|
||||
expect(thrown?.message).toBe(
|
||||
`process.exit(${ExitCodes.FATAL_AUTHENTICATION_ERROR}) called`,
|
||||
);
|
||||
{
|
||||
const errorArg = consoleErrorSpy.mock.calls[0]?.[0] as string;
|
||||
const payload = JSON.parse(errorArg);
|
||||
expect(payload.error.type).toBe('Error');
|
||||
expect(payload.error.code).toBe(1);
|
||||
expect(payload.error.code).toBe(ExitCodes.FATAL_AUTHENTICATION_ERROR);
|
||||
expect(payload.error.message).toBe('Auth error!');
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user