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
}
}
}