Skip to content

Commit 2a3630f

Browse files
fix(cli): EADDRINUSE detection via PID file fallback (#3388)
Closes #3346. isServerHealthy() falls back to PID file check when /v1/health times out. Clear EADDRINUSE error message with ag stop suggestion.
1 parent 10349f2 commit 2a3630f

1 file changed

Lines changed: 32 additions & 2 deletions

File tree

src/commands/run.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,43 @@ async function verifyAuth(baseUrl: string, authToken: string | undefined): Promi
6262
}
6363
}
6464

65-
/** Check if the server is healthy at the given base URL. */
65+
/** Check if the server is healthy at the given base URL.
66+
* #3346: Also checks PID file as a fallback when the health endpoint times out.
67+
* If the PID file exists and the process is alive, assume the server is running. */
6668
async function isServerHealthy(baseUrl: string, authToken?: string): Promise<boolean> {
6769
try {
6870
const headers: Record<string, string> = {};
6971
if (authToken) headers['Authorization'] = `Bearer ${authToken}`;
7072
const res = await fetch(`${baseUrl}/v1/health`, { headers, signal: AbortSignal.timeout(3000) });
71-
return res.ok;
73+
if (res.ok) return true;
74+
// Non-401 error or network issue — fall through to PID file check
75+
} catch {
76+
// Network error — fall through to PID file check
77+
}
78+
79+
// #3346: Fallback — check if an Aegis server PID file exists with a live process
80+
try {
81+
const { existsSync, readFileSync } = await import('node:fs');
82+
const stateDir = process.env.AEGIS_STATE_DIR || join(homedir(), '.aegis');
83+
const pidFile = join(stateDir, 'aegis.pid');
84+
if (existsSync(pidFile)) {
85+
const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);
86+
if (pid > 0 && pidExists(pid)) {
87+
return true;
88+
}
89+
}
90+
} catch {
91+
// Ignore
92+
}
93+
94+
return false;
95+
}
96+
97+
/** Check if a process with the given PID is alive. */
98+
function pidExists(pid: number): boolean {
99+
try {
100+
process.kill(pid, 0);
101+
return true;
72102
} catch {
73103
return false;
74104
}

0 commit comments

Comments
 (0)