@authup/errors
v1.0.0-beta.72
Published
Authup's error classes, error codes and code-to-HTTP-status mapping, with guards that survive JSON.
Maintainers
Readme
Where it fits
Every Authup workspace that throws or inspects an error imports this package: the server throws its classes, the HTTP error middleware maps their code to a status, and @authup/core-http-kit and the consoles read the same codes back out of response bodies. Install it directly when your own code calls the Authup API and wants to branch on what went wrong (isEntityNotFoundError(error), error.code === ErrorCode.JWT_EXPIRED), or when you build a service on Authup's server packages and want to throw errors the same middleware understands.
Installation
npm install @authup/errorsESM only. Node.js ^22.13.0 || ^23.5.0 || >=24.0.0. It has one runtime dependency, @ebec/core, and no Node-specific APIs.
Usage
Throw and map to a status
import { EntityNotFoundError, ErrorCode, httpStatusFromCode } from '@authup/errors';
const error = new EntityNotFoundError({ entity: 'user' });
error.message; // 'The user was not found.'
error.code === ErrorCode.ENTITY_NOT_FOUND; // true
httpStatusFromCode(error.code); // 404
httpStatusFromCode(ErrorCode.REGISTRATION_DISABLED); // 400, the fallback- Every class extends
AuthupErrorand sets its owncodeand default message. Pass a string to replace the message, or an options object (message,code,data,cause, andentityon the entity classes). datais merged into the JSON form, which is howLoginThrottledError,MfaThrottledErrorandDeviceVerificationThrottledErrorcarryretryAfter(seconds) to the client.httpStatusFromCode(code, fallback = 400)answers fromERROR_CODE_TO_STATUS; any code not listed there gets the fallback.codeFromHttpStatusgoes the other way for errors from a foreign source.
Recognize an error that crossed the wire
import { isAuthupError, isEntityNotFoundError, serializeError } from '@authup/errors';
declare const error: Error;
const body = JSON.parse(JSON.stringify(serializeError(error)));
if (isEntityNotFoundError(body)) {
// body.code === 'entity_not_found'
}
if (isAuthupError(body)) {
console.log(body.code, body.message);
}serializeErrorcallstoJSON()when the error has one and otherwise spreads its own properties plusnameandmessage. Use it wherever an error becomes a response body.- The guards do not need
instanceof. Each class stamps aSymbol.for(...)marker, andtoJSON()writes the marker chain as strings under the same key, so a guard recognizes the live error and the parsed JSON alike. normalizeError(value)turns anything thrown (a string, a number, an object) into a realError.
API
| Export | Kind | Purpose |
|---|---|---|
| AuthupError | class | Base class: a BaseError from @ebec/core with an optional data record merged into toJSON() |
| BadRequestError, ValidationError | class | bad_request (400) |
| UnauthorizedError, AuthHeaderError, BearerTokenMalformedError | class | identity_unauthorized, unsupported_auth_header_type, bearer_token_malformed (401) |
| EntityNotFoundError, EntityConflictError, EntityInactiveError, EntityCredentialsInvalidError | class | entity_not_found (404), entity_conflict (409), entity_inactive, invalid_credentials (400); option entity names the entity in the message |
| LoginThrottledError, MfaThrottledError, DeviceVerificationThrottledError | class | 429 with data.retryAfter |
| InternalError | class | internal_error (500) |
| isError, isAuthupError, is<Class>Error | function | Duck-type guards, one per class |
| ErrorCode | enum | Every code Authup emits: generic, entity, identity, JWT, JWK, OAuth2, permission and policy codes |
| ERROR_CODE_TO_STATUS, httpStatusFromCode, codeFromHttpStatus | const, function | Code-to-status mapping |
| serializeError, normalizeError | function | JSON boundary and unknown-value normalization |
| AuthupErrorOptions, AuthupErrorInput, AuthupEntityErrorOptions, AuthupEntityErrorInput | type | Constructor input types |
| matchesInstanceof, hasInstanceof, markInstanceof, serializeInstanceofChain, INSTANCEOF_PROPERTY, BASE_ERROR_INSTANCE | re-export | The @ebec/core marker primitives, for your own error classes |
Each class also exports its marker symbol (ENTITY_NOT_FOUND_ERROR_INSTANCE, ...).
Notes
isAuthupErrorneeds the marker chain. An object without the@instanceoflist (a hand-built{ code, message }, or a body from an older server) is not anAuthupError, even when it carries an Authup code. Readbody.codedirectly in that case.- A class guard also accepts the plain code.
isEntityNotFoundErroris true for anyAuthupErrorwhosecodeisentity_not_found, not only for instances of that class.ValidationErrorandBadRequestErrorsharebad_request, soisValidationErrorandisBadRequestErrorare both true for either class. - The status lives in the mapping, not on the error. No class carries an HTTP status; codes not in
ERROR_CODE_TO_STATUSmap to 400 by default.
License
Made with 💚
Published under the Apache 2.0 License.
