Bound shutdown and print single-line startup failures
Claude-Session: https://claude.ai/code/session_01JtuZTCMW9TyogEmBgGf8JT
This commit is contained in:
35
src/main.ts
35
src/main.ts
@@ -13,6 +13,13 @@ import { Outbound } from "./telegram/outbound.js";
|
||||
import { createScheduleTool } from "./tools/schedule.js";
|
||||
import { ensureWorkspace } from "./workspace.js";
|
||||
|
||||
function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
const timer = setTimeout(() => resolve(), ms);
|
||||
timer.unref?.();
|
||||
});
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const config = (() => {
|
||||
try {
|
||||
@@ -57,8 +64,11 @@ async function main(): Promise<void> {
|
||||
stopping = true;
|
||||
logger.info(`shutting down (${reason})`);
|
||||
await bot.stop().catch(() => undefined);
|
||||
await host?.abort().catch(() => undefined);
|
||||
await Promise.race([host?.abort().catch(() => undefined), sleep(5000)]);
|
||||
await scheduler.stop();
|
||||
// Give in-flight Telegram API calls (the online message, a reply being sent, progress-message
|
||||
// cleanup triggered by the abort) time to finish before the process exits.
|
||||
await sleep(1000);
|
||||
await host?.dispose().catch((err) => logger.warn("dispose failed", err));
|
||||
process.exit(0);
|
||||
};
|
||||
@@ -86,8 +96,20 @@ async function main(): Promise<void> {
|
||||
logger.info(`scheduler ready with ${scheduler.list().length} job(s)`);
|
||||
|
||||
bot.catch((err) => logger.error("telegram handler error", err.error));
|
||||
process.on("SIGINT", () => void shutdown("SIGINT"));
|
||||
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
||||
process.on("SIGINT", () => {
|
||||
if (stopping) {
|
||||
logger.warn("forced exit");
|
||||
process.exit(130);
|
||||
}
|
||||
void shutdown("SIGINT");
|
||||
});
|
||||
process.on("SIGTERM", () => {
|
||||
if (stopping) {
|
||||
logger.warn("forced exit");
|
||||
process.exit(130);
|
||||
}
|
||||
void shutdown("SIGTERM");
|
||||
});
|
||||
process.on("unhandledRejection", (err) => {
|
||||
logger.error("unhandled rejection", err);
|
||||
process.exit(1);
|
||||
@@ -107,6 +129,11 @@ async function main(): Promise<void> {
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err instanceof Error ? (err.stack ?? err.message) : String(err));
|
||||
if (err instanceof Error) {
|
||||
console.error(`Startup failed: ${err.name}: ${err.message}`);
|
||||
if (process.env.LOG_LEVEL === "debug" && err.stack) console.error(err.stack);
|
||||
} else {
|
||||
console.error(`Startup failed: ${String(err)}`);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user