fix: tell a missing bundled CLI from a refused or failed stat (#1700)
Some checks are pending
CI / semgrep (push) Waiting to run
Tests / test (22) (push) Waiting to run
Tests / test (22.13.0) (push) Waiting to run
Tests / test (24) (push) Waiting to run
Tests / test (26) (push) Waiting to run
Tests / test-platforms (macos-latest) (push) Waiting to run
Tests / test-platforms (windows-latest) (push) Waiting to run
Tests / desktop (push) Waiting to run
Tests / vscode (push) Waiting to run

The not-found telemetry now tells a missing bundled CLI apart from a refused or failed stat: bundled-missing, bundled-denied, bundled-unreadable.
This commit is contained in:
Resham Joshi 2026-10-08 22:37:37 +02:00 • committed by GitHub
parent 3c423996e4
commit 1bb697b7cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 1 deletions

View file

@ -298,6 +298,20 @@ describe('notFoundStage (non-sensitive telemetry enum for a not-found)', () => {
expect(notFoundStage()).toBe('bundled-missing')
})
it.skipIf(process.platform === 'win32' || process.getuid?.() === 0)('reports bundled-denied when the bundled CLI exists but cannot be stat-ed', () => {
delete process.env.CODEBURN_BIN
const locked = join(dir, 'locked')
mkdirSync(locked)
writeFileSync(join(locked, 'launch.js'), '')
chmodSync(locked, 0o000)
process.env.CODEBURN_BUNDLED_CLI = join(locked, 'launch.js')
try {
expect(notFoundStage()).toBe('bundled-denied')
} finally {
chmodSync(locked, 0o755)
}
})
it('reports bin-not-absolute for a relative CODEBURN_BIN override', () => {
process.env.CODEBURN_BIN = 'relative/codeburn'
delete process.env.CODEBURN_BUNDLED_CLI

View file

@ -42,6 +42,8 @@ export type NotFoundStage =
| 'bin-not-executable'
| 'bundled-not-absolute'
| 'bundled-missing'
| 'bundled-denied'
| 'bundled-unreadable'
| 'spawn-error'
| 'no-path-match'
@ -550,11 +552,24 @@ export function notFoundStage(): NotFoundStage {
const bundled = process.env.CODEBURN_BUNDLED_CLI
if (bundled) {
if (!isAbsolute(bundled)) return 'bundled-not-absolute'
if (!isFile(bundled)) return 'bundled-missing'
if (!isFile(bundled)) return bundledStatStage(bundled)
}
return 'no-path-match'
}
// isFile() swallows the errno: ENOENT is a vanished bundle, EACCES/EPERM one we were refused.
function bundledStatStage(p: string): NotFoundStage {
try {
statSync(p)
return 'bundled-missing'
} catch (err) {
const code = (err as NodeJS.ErrnoException).code
if (code === 'ENOENT' || code === 'ENOTDIR') return 'bundled-missing'
if (code === 'EACCES' || code === 'EPERM') return 'bundled-denied'
return 'bundled-unreadable'
}
}
/** Ask a child to exit, then insist. See {@link KILL_GRACE_MS}. The child is
* (re-)registered as active for the whole grace: a quit landing inside that
* window must still find it and SIGKILL it rather than orphan it. */