Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
3.5 kB ยท 112 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113import { ServiceError, type ServiceErrorCode } from "@openstatus/services";import { type CheckResult, streamMonitorPreview,} from "@openstatus/services/monitor";import { iteratorToStream } from "@openstatus/utils";import { z } from "zod";
import { getServiceContextFromRequest } from "@/lib/edge-context";
const SERVICE_ERROR_STATUS: Record<ServiceErrorCode, number> = { NOT_FOUND: 404, FORBIDDEN: 403, UNAUTHORIZED: 401, CONFLICT: 409, VALIDATION: 400, LIMIT_EXCEEDED: 429, PRECONDITION_FAILED: 412, INTERNAL: 500,};
const requestSchema = z.object({ monitorId: z.number(),});
const encoder = new TextEncoder();
export async function POST(req: Request) { const ctx = await getServiceContextFromRequest(req); if (!ctx) { return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401, headers: { "Content-Type": "application/json" }, }); }
let body: { monitorId: number }; try { const json = await req.json(); const parsed = requestSchema.safeParse(json); if (!parsed.success) { return new Response(JSON.stringify({ error: "Invalid request" }), { status: 400, headers: { "Content-Type": "application/json" }, }); } body = parsed.data; } catch { return new Response(JSON.stringify({ error: "Invalid JSON" }), { status: 400, headers: { "Content-Type": "application/json" }, }); }
// Resolve the monitor up-front so workspace-mismatch returns 404 instead of // a 200 stream that fails on first iteration. We "prime" the generator by // calling .next() once โ if the workspace-scope check throws, we catch it // synchronously here. Subsequent values come from the same generator. const generator = streamMonitorPreview({ ctx, input: { monitorId: body.monitorId }, });
let primed: IteratorResult<CheckResult>; try { primed = await generator.next(); } catch (err: unknown) { if (err instanceof ServiceError) { const status = SERVICE_ERROR_STATUS[err.code] ?? 500; // Don't leak `INTERNAL` messages โ they may include env-var names or // stack details. Other codes are already user-facing strings. const message = err.code === "INTERNAL" ? "Internal server error" : err.message; return new Response(JSON.stringify({ error: message }), { status, headers: { "Content-Type": "application/json" }, }); } return new Response(JSON.stringify({ error: "Internal server error" }), { status: 500, headers: { "Content-Type": "application/json" }, }); }
const wrapped = (async function* () { if (!primed.done && primed.value) { yield encoder.encode(`${JSON.stringify(primed.value)}\n`); } try { for await (const result of generator) { yield encoder.encode(`${JSON.stringify(result)}\n`); } } catch (err) { // The fan-out is `Promise.race`-based and individual region failures // are returned as error-shaped CheckResults, so we don't expect to // land here. Log so an unexpected failure isn't silent โ the stream // still closes cleanly so the client doesn't hang. console.warn( "[onboarding/checks] unexpected generator error post-prime", err, ); } })();
const stream = iteratorToStream(wrapped); return new Response(stream, { headers: { "Content-Type": "application/x-ndjson", "Cache-Control": "no-store", }, });}