mirror of https://github.com/garrytan/gstack.git
fix: use safeUnlinkQuiet in shutdown and cleanup paths
Shutdown, emergency cleanup, and disconnect paths should never throw on file deletion failures. Switched from safeUnlink (throws on EPERM) to safeUnlinkQuiet (swallows all errors) in these best-effort paths. Normal operation paths (startup, lock release) keep safeUnlink. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6a857d41ba
commit
ad38e006f6
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { safeUnlink, safeKill, isProcessAlive } from './error-handling';
|
import { safeUnlink, safeUnlinkQuiet, safeKill, isProcessAlive } from './error-handling';
|
||||||
import { resolveConfig, ensureStateDir, readVersionHash } from './config';
|
import { resolveConfig, ensureStateDir, readVersionHash } from './config';
|
||||||
|
|
||||||
const config = resolveConfig();
|
const config = resolveConfig();
|
||||||
|
|
@ -812,11 +812,11 @@ Refs: After 'snapshot', use @e1, @e2... as selectors:
|
||||||
|
|
||||||
// Clean up Chromium profile locks (can persist after crashes)
|
// Clean up Chromium profile locks (can persist after crashes)
|
||||||
for (const lockFile of ['SingletonLock', 'SingletonSocket', 'SingletonCookie']) {
|
for (const lockFile of ['SingletonLock', 'SingletonSocket', 'SingletonCookie']) {
|
||||||
safeUnlink(path.join(profileDir, lockFile));
|
safeUnlinkQuiet(path.join(profileDir, lockFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete stale state file
|
// Delete stale state file
|
||||||
safeUnlink(config.stateFile);
|
safeUnlinkQuiet(config.stateFile);
|
||||||
|
|
||||||
console.log('Launching headed Chromium with extension + sidebar agent...');
|
console.log('Launching headed Chromium with extension + sidebar agent...');
|
||||||
try {
|
try {
|
||||||
|
|
@ -945,9 +945,9 @@ Refs: After 'snapshot', use @e1, @e2... as selectors:
|
||||||
// Clean profile locks and state file
|
// Clean profile locks and state file
|
||||||
const profileDir = path.join(process.env.HOME || '/tmp', '.gstack', 'chromium-profile');
|
const profileDir = path.join(process.env.HOME || '/tmp', '.gstack', 'chromium-profile');
|
||||||
for (const lockFile of ['SingletonLock', 'SingletonSocket', 'SingletonCookie']) {
|
for (const lockFile of ['SingletonLock', 'SingletonSocket', 'SingletonCookie']) {
|
||||||
safeUnlink(path.join(profileDir, lockFile));
|
safeUnlinkQuiet(path.join(profileDir, lockFile));
|
||||||
}
|
}
|
||||||
safeUnlink(config.stateFile);
|
safeUnlinkQuiet(config.stateFile);
|
||||||
console.log('Disconnected (server was unresponsive — force cleaned).');
|
console.log('Disconnected (server was unresponsive — force cleaned).');
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ import { emitActivity, subscribe, getActivityAfter, getActivityHistory, getSubsc
|
||||||
import { inspectElement, modifyStyle, resetModifications, getModificationHistory, detachSession, type InspectorResult } from './cdp-inspector';
|
import { inspectElement, modifyStyle, resetModifications, getModificationHistory, detachSession, type InspectorResult } from './cdp-inspector';
|
||||||
// Bun.spawn used instead of child_process.spawn (compiled bun binaries
|
// Bun.spawn used instead of child_process.spawn (compiled bun binaries
|
||||||
// fail posix_spawn on all executables including /bin/bash)
|
// fail posix_spawn on all executables including /bin/bash)
|
||||||
import { safeUnlink, safeKill } from './error-handling';
|
import { safeUnlink, safeUnlinkQuiet, safeKill } from './error-handling';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as net from 'net';
|
import * as net from 'net';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
@ -1188,11 +1188,11 @@ async function shutdown() {
|
||||||
// Clean up Chromium profile locks (prevent SingletonLock on next launch)
|
// Clean up Chromium profile locks (prevent SingletonLock on next launch)
|
||||||
const profileDir = path.join(process.env.HOME || '/tmp', '.gstack', 'chromium-profile');
|
const profileDir = path.join(process.env.HOME || '/tmp', '.gstack', 'chromium-profile');
|
||||||
for (const lockFile of ['SingletonLock', 'SingletonSocket', 'SingletonCookie']) {
|
for (const lockFile of ['SingletonLock', 'SingletonSocket', 'SingletonCookie']) {
|
||||||
safeUnlink(path.join(profileDir, lockFile));
|
safeUnlinkQuiet(path.join(profileDir, lockFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up state file
|
// Clean up state file
|
||||||
safeUnlink(config.stateFile);
|
safeUnlinkQuiet(config.stateFile);
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
@ -1204,7 +1204,7 @@ process.on('SIGINT', shutdown);
|
||||||
// Defense-in-depth — primary cleanup is the CLI's stale-state detection via health check.
|
// Defense-in-depth — primary cleanup is the CLI's stale-state detection via health check.
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
process.on('exit', () => {
|
process.on('exit', () => {
|
||||||
safeUnlink(config.stateFile);
|
safeUnlinkQuiet(config.stateFile);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1223,9 +1223,9 @@ function emergencyCleanup() {
|
||||||
// Clean Chromium profile locks
|
// Clean Chromium profile locks
|
||||||
const profileDir = path.join(process.env.HOME || '/tmp', '.gstack', 'chromium-profile');
|
const profileDir = path.join(process.env.HOME || '/tmp', '.gstack', 'chromium-profile');
|
||||||
for (const lockFile of ['SingletonLock', 'SingletonSocket', 'SingletonCookie']) {
|
for (const lockFile of ['SingletonLock', 'SingletonSocket', 'SingletonCookie']) {
|
||||||
safeUnlink(path.join(profileDir, lockFile));
|
safeUnlinkQuiet(path.join(profileDir, lockFile));
|
||||||
}
|
}
|
||||||
safeUnlink(config.stateFile);
|
safeUnlinkQuiet(config.stateFile);
|
||||||
}
|
}
|
||||||
process.on('uncaughtException', (err) => {
|
process.on('uncaughtException', (err) => {
|
||||||
console.error('[browse] FATAL uncaught exception:', err.message);
|
console.error('[browse] FATAL uncaught exception:', err.message);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue