import { handleAuthError } from '../utils/authErrors';
try {
await login(credentials);
} catch (error) {
handleAuthError(error, { logToConsole: true });
setError(error);
}import { ErrorBanner } from '../components/ErrorDisplay';
<ErrorBanner
error={error}
onClose={() => setError(null)}
/><ErrorBanner error={error} onClose={() => setError(null)} /><ErrorToast error={error} duration={5000} position="top-right" /><ErrorAlert error={error} showRecoveryAction={true} /><FieldError error={fieldError} show={touched.email} />| Type | HTTP Status | User Message |
|---|---|---|
NETWORK_ERROR |
500, 502, 503, 504 | "Network error. Please check your connection..." |
UNAUTHORIZED |
401, 403 | "Invalid email or password..." |
TOKEN_EXPIRED |
401 | "Your session has expired..." |
VALIDATION_ERROR |
400 | "Invalid input. Please check your information..." |
INVALID_TOKEN |
401 | "Your session is invalid..." |
const [error, setError] = useState<unknown>(null);
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
try {
await login(credentials);
} catch (err) {
handleAuthError(err, { logToConsole: true });
setError(err);
}
};
// Clear error on input change
const handleInputChange = (e) => {
setCredentials(e.target.value);
if (error) setError(null);
};try {
const data = await apiClient.get('/endpoint');
} catch (error) {
const errorInfo = handleAuthError(error, {
clearAuthOnUnauthorized: true,
redirectToLogin: true,
});
showErrorToast(errorInfo.message);
}import { extractValidationErrors } from '../utils/authErrors';
catch (error) {
const validationErrors = extractValidationErrors(error);
validationErrors.forEach(({ field, message }) => {
setFieldError(field, message);
});
}handleAuthError(error, {
// Auto-clear auth
clearAuthOnUnauthorized: true,
clearAuthOnExpired: true,
// Logging
logToConsole: true,
logToServer: false,
// Custom handlers
onError: (errorInfo) => {
// Your custom logic
},
});import { useErrorState } from '../components/ErrorDisplay';
const { error, setError, clearError } = useErrorState(5000); // Auto-clear after 5simport { useErrorToast } from '../components/ErrorDisplay';
const { toast, showToast, hideToast } = useErrorToast();
showToast(error);| Strategy | When to Use | User Action |
|---|---|---|
RETRY |
Temporary failures | Try Again button |
RELOGIN |
Expired/invalid tokens | Sign In Again |
CHECK_CONNECTION |
Network issues | Check connection |
WAIT_AND_RETRY |
Rate limiting | Wait message |
CONTACT_SUPPORT |
Persistent issues | Contact Support link |
- π΅ INFO - Informational
- π WARNING - User input errors
- π΄ ERROR - System/auth failures
- π£ CRITICAL - Security/system failures
import {
formatErrorForDisplay,
shouldRedirectToLogin,
isRetryableError,
getRecoveryAction,
} from '../utils/authErrors';
// Get user-friendly message
const message = formatErrorForDisplay(error);
// Check if should redirect
if (shouldRedirectToLogin(error)) {
navigate('/login');
}
// Check if retryable
if (isRetryableError(error)) {
// Show retry button
}import {
AuthErrorType,
ErrorSeverity,
RecoveryStrategy,
AuthErrorInfo,
ValidationError,
} from '../utils/authErrors';import { AuthError, AuthErrorType } from '../utils/authErrors';
// Simulate error
throw new AuthError(
'Test error',
AuthErrorType.NETWORK_ERROR,
500
);/src/utils/authErrors.ts- Error handling logic/src/components/ErrorDisplay.tsx- UI components/src/components/ErrorDisplay.css- Styles/docs/AUTH_ERROR_HANDLING.md- Full documentation
β Check that error state is set β Verify error component is rendered β Check console for error details
β
Use handleAuthError() to classify
β
Check error type mapping
β
Verify HTTP status code
β Clear error on user input β Clear error after successful action β Check error auto-clear duration
- β Always handle errors in try-catch
- β Use handleAuthError() for classification
- β Display errors with UI components
- β Clear errors on user input
- β Log errors in development
- β Provide recovery actions
- β Use TypeScript types
import { useState, FormEvent } from 'react';
import { useAuth } from '../contexts/AuthContext';
import { ErrorBanner } from '../components/ErrorDisplay';
import { handleAuthError } from '../utils/authErrors';
export function LoginForm() {
const { login, loading } = useAuth();
const [credentials, setCredentials] = useState({ email: '', password: '' });
const [error, setError] = useState<unknown>(null);
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
setError(null);
try {
await login(credentials);
} catch (err) {
handleAuthError(err, { logToConsole: true });
setError(err);
}
};
return (
<form onSubmit={handleSubmit}>
<ErrorBanner error={error} onClose={() => setError(null)} />
<input
type="email"
value={credentials.email}
onChange={(e) => {
setCredentials({ ...credentials, email: e.target.value });
if (error) setError(null); // Clear error on input
}}
/>
<input
type="password"
value={credentials.password}
onChange={(e) => {
setCredentials({ ...credentials, password: e.target.value });
if (error) setError(null); // Clear error on input
}}
/>
<button type="submit" disabled={loading}>
{loading ? 'Signing in...' : 'Sign In'}
</button>
</form>
);
}π Read the full documentation: /docs/AUTH_ERROR_HANDLING.md
π¬ Check inline code comments
π Review example implementations in LoginForm and RegisterForm