@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
JavaScript
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 };