ReferenceError Handling

Error Handling

All guardo errors extend Error and set .name for easy instanceof checks. AuthError and TokenTypeError also carry a machine-readable .code.

import { AuthError, RateLimitError } from "guardo";
 
try {
  await auth.auth.loginWithOtp({ identifier, otp });
} catch (err) {
  if (err instanceof RateLimitError) {
    res.status(429).json({ error: `Retry in ${err.retryAfterSeconds}s` });
  } else if (err instanceof AuthError) {
    res.status(401).json({ error: err.message, code: err.code });
  }
}

Error classes

ClassThrown byExtra property
AuthErrorauth.auth.* - bad OTP, revoked session, user not found, refresh-token reuse.code?: GuardoErrorCode
RateLimitErrorauth.otp.send() - too many requests.retryAfterSeconds
TokenTypeErrorauth.jwt.verify*() - wrong token type.code?: GuardoErrorCode
OAuthErrorauth.oauth.* - unknown provider, bad state, exchange/profile failure.code?: GuardoErrorCode
JsonWebTokenErrorauth.jwt.verify*() - invalid signature (from jsonwebtoken)-
TokenExpiredErrorauth.jwt.verify*() - expired token (from jsonwebtoken)-

AuthError, RateLimitError, TokenTypeError, and OAuthError are exported from the package root. JsonWebTokenError / TokenExpiredError come from the jsonwebtoken dependency.

auth.otp.verify() does not throw on a bad code - it returns { success: false, verified: false, error, code }. Only loginWithOtp turns a failed verification into a thrown AuthError.

GuardoErrorCode

Machine-readable codes attached to AuthError.code, TokenTypeError.code, and VerifyOtpResult.code. Middleware 401/403 JSON responses also include a code field.

CodeMeaning
OTP_EXPIREDNo valid OTP found for the identifier.
OTP_INVALIDOTP didn’t match.
OTP_MAX_ATTEMPTSToo many failed attempts; OTP invalidated.
OTP_RATE_LIMITEDOTP verify rate limit hit.
SESSION_REVOKEDThe session backing the token was revoked.
SESSION_NOT_FOUNDNo authenticated user / session.
TOKEN_EXPIREDToken has expired.
TOKEN_INVALIDToken missing or malformed.
TOKEN_TYPE_MISMATCHAccess token used where a refresh token was expected, or vice-versa.
USER_NOT_FOUNDresolveUser returned null and no onNewUser was set.
REFRESH_TOKEN_REUSEA revoked refresh token was replayed - all sessions revoked.
INVALID_ARGUMENTA method was called with the wrong argument type (e.g. logout({ sessionId }) instead of logout(sessionId)).
FORBIDDENRole check failed.
OAUTH_NOT_CONFIGUREDNo redirectUri configured or passed to oauth.start().
OAUTH_PROVIDER_NOT_FOUNDNo provider registered under the given id.
OAUTH_STATE_INVALIDMissing, expired, replayed, or mismatched OAuth state (CSRF).
OAUTH_EXCHANGE_FAILEDThe provider’s token endpoint rejected the code exchange.
OAUTH_PROFILE_FAILEDFetching the user profile from the provider failed.