Errors
Depending on the request payload, the request might not be successfully. In that case, the api responds with an error payload, which looks like this:
{
"message": "The application could not fulfill the request",
"code": "bad_request",
"statusCode": 400
}The error codes can be used to distinguish between different error responses. The following error codes are available:
export enum ErrorCode {
HEADER_INVALID = 'invalid_header',
HEADER_AUTH_TYPE_UNSUPPORTED = 'unsupported_auth_header_type',
CREDENTIALS_INVALID = 'invalid_credentials',
ENTITY_INACTIVE = 'inactive_entity',
TOKEN_REDIRECT_URI_MISMATCH = 'redirect_uri_mismatch',
TOKEN_INVALID = 'invalid_token',
TOKEN_INACTIVE = 'inactive_token',
TOKEN_EXPIRED = 'expired_token',
TOKEN_CLIENT_INVALID = 'invalid_client',
TOKEN_GRANT_INVALID = 'invalid_grant',
TOKEN_GRANT_TYPE_UNSUPPORTED = 'unsupported_token_grant_type',
TOKEN_SCOPE_INVALID = 'invalid_scope',
TOKEN_SCOPE_INSUFFICIENT = 'insufficient_scope',
TOKEN_SUB_KIND_INVALID = 'invalid_token_sub_kind',
PERMISSION_NOT_FOUND = 'permission_not_found',
PERMISSION_DENIED = 'permission_denied',
PERMISSION_EVALUATION_FAILED = 'permission_evaluation_failed',
POLICY_EVALUATOR_NOT_FOUND = 'policy_evaluator_not_found',
POLICY_EVALUATOR_NOT_PROCESSABLE = 'policy_evaluator_not_processable',
POLICY_EVALUATOR_CONTEXT_INVALID = 'policy_evaluator_context_invalid',
}Helpers
@authup/errors exports a small toolkit for working with thrown values:
isError
Duck-typed guard for Error. Matches anything carrying the standard name / message / stack triplet, regardless of class or realm. Prefer this over instanceof Error whenever cross-realm boundaries (worker threads, duplicate-module copies) are in play.
import { isError } from '@authup/errors';
if (isError(input)) {
// input is typed as Error
}normalizeError
Coerce an arbitrary thrown value into a real Error instance. Useful at error-pipeline boundaries (catch blocks, error middleware) where TypeScript hands you unknown but downstream code wants something with .name / .message.
import { normalizeError } from '@authup/errors';
try {
/* ... */
} catch (e) {
const error = normalizeError(e); // string / unknown → Error
throw error;
}serializeError
Convert an Error into a plain object suitable for embedding in a JSON response body. Calls error.toJSON() if present, preserving every attribute the error chose to surface (code, cause, errors, issues, data, ...). Falls back to spreading the Error's enumerable own properties alongside the standard name / message pair.
import { normalizeError, serializeError } from '@authup/errors';
try {
/* ... */
} catch (e) {
return {
status: 'error',
data: serializeError(normalizeError(e)),
};
}isAuthupError
Discriminates an AuthupError (or any subclass) from arbitrary errors. Uses the cross-realm markInstanceof chain (fast path) plus a shape check (slow path).
import { isAuthupError } from '@authup/errors';
if (isAuthupError(error)) {
// error has .code, .issues, ...
}