UNPKG

@intuitionrobotics/thunderstorm

Version:
77 lines 3.44 kB
import { BadImplementationException, dispatch_onServerError, isErrorOfType, MUSTNeverHappenException, ServerErrorSeverity, ValidationException } from "@intuitionrobotics/ts-common"; import { ApiException } from "../../exceptions.js"; import { Storm } from "../../core/Storm.js"; import {} from "./server-api.js"; /** * The shared error-composition pipeline, extracted verbatim from * `ServerApi.call()`'s catch block. BOTH the legacy `ServerApi` (its own * internal catch) and the new app-level `terminalErrorHandler` route errors * through this ONE function, so the two endpoint styles can never drift. * * It normalizes any thrown value to an `ApiException`, logs it, maps the * response code to a `ServerErrorSeverity`, and — unless the exception opts * out via `setDispatchError(false)` — composes an error message through the * `Storm` instance and dispatches `dispatch_onServerError`. * * Returns the resolved `ApiException`; the CALLER decides how to write it * (`response.serverError` for 500, `response.exception` otherwise). The * `logger` lets callers attribute the logs to themselves (`ServerApi` passes * `this`; the app-level handler passes its own module logger). */ export async function composeApiError(err, requestData, logger) { let dispatchError = true; let e = err; let severity = ServerErrorSeverity.Warning; if (typeof e === "string") e = new BadImplementationException(`String was thrown: ${e}`); if (!(e instanceof Error) && typeof e === "object") e = new BadImplementationException(`Object instance was thrown: ${JSON.stringify(e)}`); try { logger.logErrorBold(e); } catch (e2) { logger.logErrorBold("Error while handling error on request...", e2); logger.logErrorBold(`Original error thrown: ${JSON.stringify(e)}`); logger.logErrorBold(`-- Someone was stupid... you MUST only throw an Error and not objects or strings!! --`); } if (isErrorOfType(e, ValidationException)) e = new ApiException(400, "Validator exception", e); if (!isErrorOfType(e, ApiException)) e = new ApiException(500, "Unexpected server error", e); const apiException = isErrorOfType(e, ApiException); if (!apiException) throw new MUSTNeverHappenException("MUST NEVER REACH HERE!!!"); dispatchError = apiException.getDispatchError(); if (apiException.responseCode >= 500) severity = ServerErrorSeverity.Error; else if (apiException.responseCode >= 400) severity = ServerErrorSeverity.Warning; switch (apiException.responseCode) { case 401: severity = ServerErrorSeverity.Debug; break; case 404: severity = ServerErrorSeverity.Info; break; case 403: severity = ServerErrorSeverity.Warning; break; case 500: severity = ServerErrorSeverity.Critical; break; } if (dispatchError) { try { const storm = Storm.getInstance(); if (storm) { const message = await storm.errorMessageComposer(requestData, apiException); await dispatch_onServerError.dispatchModuleAsync(severity, message); } } catch (e) { logger.logError("Error while handing server error", e); } } return apiException; } //# sourceMappingURL=api-error.js.map