Standardize exit codes (#7055)

This commit is contained in:
Tommaso Sciortino
2025-08-25 21:44:45 -07:00
committed by GitHub
parent 415a36a195
commit 7e31577813
10 changed files with 116 additions and 97 deletions

View File

@@ -17,6 +17,7 @@ import {
} from '../config/settings.js';
import { promisify } from 'node:util';
import type { Config, SandboxConfig } from '@google/gemini-cli-core';
import { FatalSandboxError } from '@google/gemini-cli-core';
import { ConsolePatcher } from '../ui/utils/ConsolePatcher.js';
const execAsync = promisify(exec);
@@ -198,8 +199,9 @@ export async function start_sandbox(
if (config.command === 'sandbox-exec') {
// disallow BUILD_SANDBOX
if (process.env['BUILD_SANDBOX']) {
console.error('ERROR: cannot BUILD_SANDBOX when using macOS Seatbelt');
process.exit(1);
throw new FatalSandboxError(
'Cannot BUILD_SANDBOX when using macOS Seatbelt',
);
}
const profile = (process.env['SEATBELT_PROFILE'] ??= 'permissive-open');
@@ -214,10 +216,9 @@ export async function start_sandbox(
);
}
if (!fs.existsSync(profileFile)) {
console.error(
`ERROR: missing macos seatbelt profile file '${profileFile}'`,
throw new FatalSandboxError(
`Missing macos seatbelt profile file '${profileFile}'`,
);
process.exit(1);
}
// Log on STDERR so it doesn't clutter the output on STDOUT
console.error(`using macos seatbelt (profile: ${profile}) ...`);
@@ -325,13 +326,12 @@ export async function start_sandbox(
console.error(data.toString());
});
proxyProcess.on('close', (code, signal) => {
console.error(
`ERROR: proxy command '${proxyCommand}' exited with code ${code}, signal ${signal}`,
);
if (sandboxProcess?.pid) {
process.kill(-sandboxProcess.pid, 'SIGTERM');
}
process.exit(1);
throw new FatalSandboxError(
`Proxy command '${proxyCommand}' exited with code ${code}, signal ${signal}`,
);
});
console.log('waiting for proxy to start ...');
await execAsync(
@@ -366,11 +366,10 @@ export async function start_sandbox(
// note this can only be done with binary linked from gemini-cli repo
if (process.env['BUILD_SANDBOX']) {
if (!gcPath.includes('gemini-cli/packages/')) {
console.error(
'ERROR: cannot build sandbox using installed gemini binary; ' +
throw new FatalSandboxError(
'Cannot build sandbox using installed gemini binary; ' +
'run `npm link ./packages/cli` under gemini-cli repo to switch to linked binary.',
);
process.exit(1);
} else {
console.error('building sandbox ...');
const gcRoot = gcPath.split('/packages/')[0];
@@ -403,10 +402,9 @@ export async function start_sandbox(
image === LOCAL_DEV_SANDBOX_IMAGE_NAME
? 'Try running `npm run build:all` or `npm run build:sandbox` under the gemini-cli repo to build it locally, or check the image name and your network connection.'
: 'Please check the image name, your network connection, or notify gemini-cli-dev@google.com if the issue persists.';
console.error(
`ERROR: Sandbox image '${image}' is missing or could not be pulled. ${remedy}`,
throw new FatalSandboxError(
`Sandbox image '${image}' is missing or could not be pulled. ${remedy}`,
);
process.exit(1);
}
// use interactive mode and auto-remove container on exit
@@ -484,17 +482,15 @@ export async function start_sandbox(
mount = `${from}:${to}:${opts}`;
// check that from path is absolute
if (!path.isAbsolute(from)) {
console.error(
`ERROR: path '${from}' listed in SANDBOX_MOUNTS must be absolute`,
throw new FatalSandboxError(
`Path '${from}' listed in SANDBOX_MOUNTS must be absolute`,
);
process.exit(1);
}
// check that from path exists on host
if (!fs.existsSync(from)) {
console.error(
`ERROR: missing mount path '${from}' listed in SANDBOX_MOUNTS`,
throw new FatalSandboxError(
`Missing mount path '${from}' listed in SANDBOX_MOUNTS`,
);
process.exit(1);
}
console.error(`SANDBOX_MOUNTS: ${from} -> ${to} (${opts})`);
args.push('--volume', mount);
@@ -665,10 +661,9 @@ export async function start_sandbox(
console.error(`SANDBOX_ENV: ${env}`);
args.push('--env', env);
} else {
console.error(
'ERROR: SANDBOX_ENV must be a comma-separated list of key=value pairs',
throw new FatalSandboxError(
'SANDBOX_ENV must be a comma-separated list of key=value pairs',
);
process.exit(1);
}
}
}
@@ -776,13 +771,12 @@ export async function start_sandbox(
console.error(data.toString().trim());
});
proxyProcess.on('close', (code, signal) => {
console.error(
`ERROR: proxy container command '${proxyContainerCommand}' exited with code ${code}, signal ${signal}`,
);
if (sandboxProcess?.pid) {
process.kill(-sandboxProcess.pid, 'SIGTERM');
}
process.exit(1);
throw new FatalSandboxError(
`Proxy container command '${proxyContainerCommand}' exited with code ${code}, signal ${signal}`,
);
});
console.log('waiting for proxy to start ...');
await execAsync(