UNPKG

@intuitionrobotics/thunderstorm

Version:
53 lines 2.33 kB
import { Logger } from "@intuitionrobotics/ts-common"; import {} from "express"; import { parse } from "url"; import { composeApiError } from "./api-error.js"; import { apiDebug } from "./server-api.js"; import { HttpMethod } from "../../../shared/types.js"; const logger = new Logger("terminalErrorHandler"); /** * Build the `HttpRequestData` shape (the same one `ServerApi.call()` assembles, * server-api.ts:154-161) from a raw Express request, for the Storm error * composer. */ function requestDataFrom(req) { return { method: (req.method ? req.method.toLowerCase() : HttpMethod.ALL), originalUrl: req.path, headers: req.headers, url: req.url, query: parse(req.url, true).query, body: req.body }; } /** * The single app-level error handler for raw (`handler()`-wrapped) endpoints. * Register it LAST, after the router (see `ApiFunction`). It routes the error * through the shared `composeApiError` pipeline, then writes the response with * the same shape + `apiDebug.enabled` gating as `ApiResponse.serverError` / * `ApiResponse.exception` (server-api.ts:428-440). * * Legacy `ServerApi` endpoints never reach here (they catch internally), so * this is purely additive. */ export function terminalErrorHandler() { return async (err, req, res, next) => { // Headers already sent (stream/SSE) → can't rewrite the response; let // Express's default finalize the (already-broken) connection. if (res.headersSent) return next(err); const apiException = await composeApiError(err, requestDataFrom(req), logger); const responseBody = apiException.responseBody; if (!apiDebug.enabled) delete responseBody.debugMessage; if (apiException.responseCode === 500) { const cause = apiException.cause; const stack = cause ? cause.stack : apiException.stack; const message = (cause ? cause.message : apiException.message) || ""; res.status(500).set("Content-Type", "text/plain").send(apiDebug.enabled && stack ? stack : message); return; } res.status(apiException.responseCode).set("Content-Type", "application/json").send(JSON.stringify(responseBody, null, 2)); }; } //# sourceMappingURL=app-middleware.js.map