Skip to main content

Error Handling

All SDK methods throw NAuthClientError on failure. This page covers error patterns, common error codes, and retry strategies.

NAuthClientError​

Every error from the SDK is an instance of NAuthClientError:

import { NAuthClientError } from '@nauth-toolkit/client';

try {
await client.login(email, password);
} catch (err) {
if (err instanceof NAuthClientError) {
err.code; // Error code string (e.g., 'AUTH_INVALID_CREDENTIALS')
err.message; // Human-readable message
err.statusCode; // HTTP status (e.g., 401, 429)
err.details; // Additional context (optional)
}
}

Common Error Codes​

Authentication Errors​

CodeWhenStatus
AUTH_INVALID_CREDENTIALSWrong email or password401
AUTH_ACCOUNT_LOCKEDToo many failed attempts423
AUTH_ACCOUNT_INACTIVEAccount disabled by admin403
USER_NOT_FOUNDEmail not registered404
SIGNUP_EMAIL_EXISTSSignup with existing email409

Challenge Errors​

CodeWhenStatus
VERIFY_CODE_INVALIDWrong verification code400
VERIFY_CODE_EXPIREDVerification code expired400
CHALLENGE_EXPIREDChallenge session timed out401
CHALLENGE_MAX_ATTEMPTSToo many wrong codes429

MFA Errors​

CodeWhenStatus
MFA_SETUP_REQUIREDMFA setup required before login403

Rate Limiting​

CodeWhenStatus
RATE_LIMIT_LOGINLogin rate limit exceeded429

Network Errors​

CodeWhenStatus
NETWORK_ERRORRequest failed (offline, timeout)—
REQUEST_TIMEOUTRequest exceeded timeout—

Error Handling Patterns​

Per-Action Error Handling​

src/app/login/login.component.ts
import { NAuthClientError } from '@nauth-toolkit/client';

async login(): Promise<void> {
try {
const response = await this.auth.login(this.email, this.password);
if (response.challengeName) {
this.router.navigate(['/auth/challenge']);
} else {
this.router.navigate(['/dashboard']);
}
} catch (err) {
if (err instanceof NAuthClientError) {
switch (err.code) {
case 'AUTH_INVALID_CREDENTIALS':
this.error = 'Invalid email or password';
break;
case 'AUTH_ACCOUNT_LOCKED':
this.error = 'Account locked. Try again later.';
break;
case 'RATE_LIMIT_LOGIN':
this.error = 'Too many attempts. Please wait.';
break;
default:
this.error = err.message;
}
}
}
}

Global Error Handler​

Configure a global handler via the onError callback:

const client = new NAuthClient({
baseUrl: 'https://api.example.com/auth',
tokenDelivery: 'cookies',
onError: (error) => {
// Log to monitoring service
if (error.code === 'NETWORK_ERROR') {
showToast('Network error. Check your connection.');
}
},
});

Rate Limiting​

When you receive a rate limit error (HTTP 429), the response may include a retryAfter value in details:

try {
await client.resendCode(session);
} catch (err) {
if (err instanceof NAuthClientError && err.statusCode === 429) {
const retryAfter = (err.details as { retryAfter?: number })?.retryAfter ?? 60;
setCountdown(retryAfter);
}
}

Checking Error Codes​

Use the isCode() helper:

try {
await client.login(email, password);
} catch (err) {
if (err instanceof NAuthClientError) {
if (err.isCode('AUTH_INVALID_CREDENTIALS')) {
// Handle invalid credentials
}
}
}