mirror of https://github.com/garrytan/gstack.git
fix: log non-ENOENT errors in ensureStateDir() instead of silently swallowing
Replace bare catch {} with ENOENT-only silence. Non-ENOENT errors (EACCES,
ENOSPC) are now logged to .gstack/browse-server.log. Includes test for
permission-denied scenario with chmod 444.
This commit is contained in:
parent
2aa745cb0e
commit
8cb905ec27
|
|
@ -98,8 +98,17 @@ export function ensureStateDir(config: BrowseConfig): void {
|
||||||
const separator = content.endsWith('\n') ? '' : '\n';
|
const separator = content.endsWith('\n') ? '' : '\n';
|
||||||
fs.appendFileSync(gitignorePath, `${separator}.gstack/\n`);
|
fs.appendFileSync(gitignorePath, `${separator}.gstack/\n`);
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (err: any) {
|
||||||
// No .gitignore or unreadable — skip
|
if (err.code !== 'ENOENT') {
|
||||||
|
// Write warning to server log (visible even in daemon mode)
|
||||||
|
const logPath = path.join(config.stateDir, 'browse-server.log');
|
||||||
|
try {
|
||||||
|
fs.appendFileSync(logPath, `[${new Date().toISOString()}] Warning: could not update .gitignore at ${gitignorePath}: ${err.message}\n`);
|
||||||
|
} catch {
|
||||||
|
// stateDir write failed too — nothing more we can do
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ENOENT (no .gitignore) — skip silently
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,27 @@ describe('config', () => {
|
||||||
fs.rmSync(tmpDir, { recursive: true, force: true });
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('logs warning to browse-server.log on non-ENOENT gitignore error', () => {
|
||||||
|
const tmpDir = path.join(os.tmpdir(), `browse-gitignore-test-${Date.now()}`);
|
||||||
|
fs.mkdirSync(tmpDir, { recursive: true });
|
||||||
|
// Create a read-only .gitignore (no .gstack/ entry → would try to append)
|
||||||
|
fs.writeFileSync(path.join(tmpDir, '.gitignore'), 'node_modules/\n');
|
||||||
|
fs.chmodSync(path.join(tmpDir, '.gitignore'), 0o444);
|
||||||
|
const config = resolveConfig({ BROWSE_STATE_FILE: path.join(tmpDir, '.gstack', 'browse.json') });
|
||||||
|
ensureStateDir(config); // should not throw
|
||||||
|
// Verify warning was written to server log
|
||||||
|
const logPath = path.join(config.stateDir, 'browse-server.log');
|
||||||
|
expect(fs.existsSync(logPath)).toBe(true);
|
||||||
|
const logContent = fs.readFileSync(logPath, 'utf-8');
|
||||||
|
expect(logContent).toContain('Warning: could not update .gitignore');
|
||||||
|
// .gitignore should remain unchanged
|
||||||
|
const gitignoreContent = fs.readFileSync(path.join(tmpDir, '.gitignore'), 'utf-8');
|
||||||
|
expect(gitignoreContent).toBe('node_modules/\n');
|
||||||
|
// Cleanup
|
||||||
|
fs.chmodSync(path.join(tmpDir, '.gitignore'), 0o644);
|
||||||
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||||
|
});
|
||||||
|
|
||||||
test('skips if no .gitignore exists', () => {
|
test('skips if no .gitignore exists', () => {
|
||||||
const tmpDir = path.join(os.tmpdir(), `browse-gitignore-test-${Date.now()}`);
|
const tmpDir = path.join(os.tmpdir(), `browse-gitignore-test-${Date.now()}`);
|
||||||
fs.mkdirSync(tmpDir, { recursive: true });
|
fs.mkdirSync(tmpDir, { recursive: true });
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue