feat: normalize failures through a stable registry
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import { systemClock } from "../../application/ports/clock-port.js";
|
||||
import { getApiOperation } from "../../contracts/api-operations.js";
|
||||
import {
|
||||
createFailure as failure,
|
||||
kindForStatus as statusKind,
|
||||
} from "../../contracts/errors.js";
|
||||
import { retryDelay, shouldRetry } from "./retry-policy.js";
|
||||
import {
|
||||
validateEnvelope,
|
||||
@@ -36,16 +40,6 @@ const noAuthSession =
|
||||
* { ok: false, error: HttpFailure }} HttpResult
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* code?: string,
|
||||
* httpStatus?: number,
|
||||
* requestId?: string,
|
||||
* traceId?: string,
|
||||
* retryAfterMs?: number
|
||||
* }} FailureDetails
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* baseUrl: string,
|
||||
@@ -378,52 +372,6 @@ async function recoverSession(authSession, operation, originalFailure) {
|
||||
* @param {FailureDetails} [details]
|
||||
* @returns {HttpFailure}
|
||||
*/
|
||||
function failure(kind, operationId, attempt, details = {}) {
|
||||
const retryable = new Set([
|
||||
"NETWORK_UNREACHABLE",
|
||||
"REQUEST_TIMEOUT",
|
||||
"RATE_LIMITED",
|
||||
"SERVER_FAILURE",
|
||||
]).has(kind);
|
||||
const action =
|
||||
kind === "AUTH_REQUIRED"
|
||||
? "reauth"
|
||||
: retryable
|
||||
? "retry"
|
||||
: kind === "REQUEST_ABORTED"
|
||||
? "none"
|
||||
: "contact-support";
|
||||
|
||||
return Object.freeze({
|
||||
kind,
|
||||
code: details.code ?? kind,
|
||||
retryable,
|
||||
operationId,
|
||||
attemptCount: attempt + 1,
|
||||
...(details.httpStatus === undefined ? {} : { httpStatus: details.httpStatus }),
|
||||
...(details.requestId ? { requestId: details.requestId } : {}),
|
||||
...(details.traceId ? { traceId: details.traceId } : {}),
|
||||
...(details.retryAfterMs === undefined
|
||||
? {}
|
||||
: { retryAfterMs: details.retryAfterMs }),
|
||||
userMessageKey: `error.${kind.toLowerCase()}`,
|
||||
action,
|
||||
});
|
||||
}
|
||||
|
||||
/** @param {number} status */
|
||||
function statusKind(status) {
|
||||
if (status === 401) return "AUTH_REQUIRED";
|
||||
if (status === 403) return "FORBIDDEN";
|
||||
if (status === 404) return "NOT_FOUND";
|
||||
if (status === 409) return "CONFLICT";
|
||||
if (status === 422) return "VALIDATION_REJECTED";
|
||||
if (status === 429) return "RATE_LIMITED";
|
||||
if (status >= 500) return "SERVER_FAILURE";
|
||||
if (status >= 400) return "UNKNOWN_CLIENT_FAILURE";
|
||||
return "ENVELOPE_MISMATCH";
|
||||
}
|
||||
|
||||
/** @param {unknown} envelope */
|
||||
function safeBackendCode(envelope) {
|
||||
if (!envelope || typeof envelope !== "object") return "HTTP_FAILURE";
|
||||
|
||||
Reference in New Issue
Block a user