Skip to content

Commit 78e31b9

Browse files
committed
fix: harden signal shutdown error handling
1 parent 0246a2c commit 78e31b9

1 file changed

Lines changed: 37 additions & 10 deletions

File tree

src/server/start-mcp-server.ts

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,45 @@ export async function startMcpServer(): Promise<void> {
3535

3636
await startServer(server);
3737

38-
process.on('SIGTERM', async () => {
39-
await shutdownXcodeToolsBridge();
40-
await getDefaultDebuggerManager().disposeAll();
41-
await server.close();
42-
process.exit(0);
38+
let shuttingDown = false;
39+
const shutdown = async (signal: NodeJS.Signals): Promise<void> => {
40+
if (shuttingDown) return;
41+
shuttingDown = true;
42+
43+
log('info', `Received ${signal}; shutting down MCP server`);
44+
45+
let exitCode = 0;
46+
47+
try {
48+
await shutdownXcodeToolsBridge();
49+
} catch (error) {
50+
exitCode = 1;
51+
log('error', `Failed to shutdown Xcode tools bridge: ${String(error)}`);
52+
}
53+
54+
try {
55+
await getDefaultDebuggerManager().disposeAll();
56+
} catch (error) {
57+
exitCode = 1;
58+
log('error', `Failed to dispose debugger sessions: ${String(error)}`);
59+
}
60+
61+
try {
62+
await server.close();
63+
} catch (error) {
64+
exitCode = 1;
65+
log('error', `Failed to close MCP server: ${String(error)}`);
66+
}
67+
68+
process.exit(exitCode);
69+
};
70+
71+
process.once('SIGTERM', () => {
72+
void shutdown('SIGTERM');
4373
});
4474

45-
process.on('SIGINT', async () => {
46-
await shutdownXcodeToolsBridge();
47-
await getDefaultDebuggerManager().disposeAll();
48-
await server.close();
49-
process.exit(0);
75+
process.once('SIGINT', () => {
76+
void shutdown('SIGINT');
5077
});
5178

5279
log('info', `XcodeBuildMCP server (version ${version}) started successfully`);

0 commit comments

Comments
 (0)