@intuitionrobotics/thunderstorm
Version:
77 lines • 3.44 kB
JavaScript
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