This commit is contained in:
nate 2026-04-08 14:45:26 +04:00
parent 1434330545
commit c74ee9856e
3 changed files with 25 additions and 10 deletions

View File

@ -7,6 +7,15 @@ import { channels } from "./routes/channels";
import { migrate } from "./db";
import { SECURITY_HEADERS } from "../../shared/auth";
// Global safety net: never let an unhandled rejection take down the API process.
// We'd rather log loudly and stay up than 502 every monitor on a single bug.
process.on("unhandledRejection", (reason) => {
console.error("[unhandledRejection]", reason);
});
process.on("uncaughtException", (err) => {
console.error("[uncaughtException]", err);
});
await migrate();
const elysia = new Elysia()

View File

@ -26,6 +26,9 @@ export async function dispatch(channel: ChannelRow, event: NotificationEvent): P
}
export async function dispatchForMonitor(monitorId: string, event: NotificationEvent): Promise<void> {
// Belt-and-braces: this is called fire-and-forget from the ingest path, so any
// error escaping here would become an unhandled rejection and crash the process.
try {
const channels = await sql<ChannelRow[]>`
SELECT c.id, c.account_id, c.name, c.kind, c.config, c.enabled
FROM notification_channels c
@ -34,6 +37,9 @@ export async function dispatchForMonitor(monitorId: string, event: NotificationE
`;
if (channels.length === 0) return;
await Promise.all(channels.map((c) => dispatch(c, event)));
} catch (e) {
console.warn(`[notify] dispatchForMonitor failed for ${monitorId}:`, e);
}
}
export type { NotificationEvent, ChannelRow, MonitorContext, PingContext } from "./types";

View File

@ -169,11 +169,11 @@ export const ingest = new Elysia()
: { kind: "down", monitor: monitorCtx, ping: pingCtx };
// Suppress the synthetic "up" on a brand-new monitor (no prior state).
if (!(body.up && prevState === null)) {
void dispatchForMonitor(monitor_check.id, event);
dispatchForMonitor(monitor_check.id, event).catch((e) => console.warn("[notify] dispatch escaped:", e));
}
}
if (certEvent && days != null) {
void dispatchForMonitor(monitor_check.id, { kind: "cert", monitor: monitorCtx, days });
dispatchForMonitor(monitor_check.id, { kind: "cert", monitor: monitorCtx, days }).catch((e) => console.warn("[notify] cert dispatch escaped:", e));
}
return { ok: true };