UNPKG

@orpc/client

Version:

<div align="center"> <image align="center" src="https://orpc.dev/logo.webp" width=280 alt="oRPC logo" /> </div>

172 lines (168 loc) • 5.17 kB
import { resolveMaybeOptionalOptions, getConstructor, isObject } from '@orpc/shared'; const ORPC_CLIENT_PACKAGE_NAME = "@orpc/client"; const ORPC_CLIENT_PACKAGE_VERSION = "1.13.4"; const COMMON_ORPC_ERROR_DEFS = { BAD_REQUEST: { status: 400, message: "Bad Request" }, UNAUTHORIZED: { status: 401, message: "Unauthorized" }, FORBIDDEN: { status: 403, message: "Forbidden" }, NOT_FOUND: { status: 404, message: "Not Found" }, METHOD_NOT_SUPPORTED: { status: 405, message: "Method Not Supported" }, NOT_ACCEPTABLE: { status: 406, message: "Not Acceptable" }, TIMEOUT: { status: 408, message: "Request Timeout" }, CONFLICT: { status: 409, message: "Conflict" }, PRECONDITION_FAILED: { status: 412, message: "Precondition Failed" }, PAYLOAD_TOO_LARGE: { status: 413, message: "Payload Too Large" }, UNSUPPORTED_MEDIA_TYPE: { status: 415, message: "Unsupported Media Type" }, UNPROCESSABLE_CONTENT: { status: 422, message: "Unprocessable Content" }, TOO_MANY_REQUESTS: { status: 429, message: "Too Many Requests" }, CLIENT_CLOSED_REQUEST: { status: 499, message: "Client Closed Request" }, INTERNAL_SERVER_ERROR: { status: 500, message: "Internal Server Error" }, NOT_IMPLEMENTED: { status: 501, message: "Not Implemented" }, BAD_GATEWAY: { status: 502, message: "Bad Gateway" }, SERVICE_UNAVAILABLE: { status: 503, message: "Service Unavailable" }, GATEWAY_TIMEOUT: { status: 504, message: "Gateway Timeout" } }; function fallbackORPCErrorStatus(code, status) { return status ?? COMMON_ORPC_ERROR_DEFS[code]?.status ?? 500; } function fallbackORPCErrorMessage(code, message) { return message || COMMON_ORPC_ERROR_DEFS[code]?.message || code; } const GLOBAL_ORPC_ERROR_CONSTRUCTORS_SYMBOL = Symbol.for(`__${ORPC_CLIENT_PACKAGE_NAME}@${ORPC_CLIENT_PACKAGE_VERSION}/error/ORPC_ERROR_CONSTRUCTORS__`); void (globalThis[GLOBAL_ORPC_ERROR_CONSTRUCTORS_SYMBOL] ??= /* @__PURE__ */ new WeakSet()); const globalORPCErrorConstructors = globalThis[GLOBAL_ORPC_ERROR_CONSTRUCTORS_SYMBOL]; class ORPCError extends Error { defined; code; status; data; constructor(code, ...rest) { const options = resolveMaybeOptionalOptions(rest); if (options.status !== void 0 && !isORPCErrorStatus(options.status)) { throw new Error("[ORPCError] Invalid error status code."); } const message = fallbackORPCErrorMessage(code, options.message); super(message, options); this.code = code; this.status = fallbackORPCErrorStatus(code, options.status); this.defined = options.defined ?? false; this.data = options.data; } toJSON() { return { defined: this.defined, code: this.code, status: this.status, message: this.message, data: this.data }; } /** * Workaround for Next.js where different contexts use separate * dependency graphs, causing multiple ORPCError constructors existing and breaking * `instanceof` checks across contexts. * * This is particularly problematic with "Optimized SSR", where orpc-client * executes in one context but is invoked from another. When an error is thrown * in the execution context, `instanceof ORPCError` checks fail in the * invocation context due to separate class constructors. * * @todo Remove this and related code if Next.js resolves the multiple dependency graph issue. */ static [Symbol.hasInstance](instance) { if (globalORPCErrorConstructors.has(this)) { const constructor = getConstructor(instance); if (constructor && globalORPCErrorConstructors.has(constructor)) { return true; } } return super[Symbol.hasInstance](instance); } } globalORPCErrorConstructors.add(ORPCError); function isDefinedError(error) { return error instanceof ORPCError && error.defined; } function toORPCError(error) { return error instanceof ORPCError ? error : new ORPCError("INTERNAL_SERVER_ERROR", { message: "Internal server error", cause: error }); } function isORPCErrorStatus(status) { return status < 200 || status >= 400; } function isORPCErrorJson(json) { if (!isObject(json)) { return false; } const validKeys = ["defined", "code", "status", "message", "data"]; if (Object.keys(json).some((k) => !validKeys.includes(k))) { return false; } return "defined" in json && typeof json.defined === "boolean" && "code" in json && typeof json.code === "string" && "status" in json && typeof json.status === "number" && isORPCErrorStatus(json.status) && "message" in json && typeof json.message === "string"; } function createORPCErrorFromJson(json, options = {}) { return new ORPCError(json.code, { ...options, ...json }); } export { COMMON_ORPC_ERROR_DEFS as C, ORPC_CLIENT_PACKAGE_NAME as O, ORPC_CLIENT_PACKAGE_VERSION as a, fallbackORPCErrorMessage as b, ORPCError as c, isORPCErrorStatus as d, isORPCErrorJson as e, fallbackORPCErrorStatus as f, createORPCErrorFromJson as g, isDefinedError as i, toORPCError as t };