Skip to main content

Error Handling Template

Document Control​

  • Last Updated: February 4, 2025
  • Version: 1.0.0
  • Status: Active
  • Owner: Development Team
  • Next Review: May 4, 2025

Error Response Format​

Standard Error Response​

{
"status": "error",
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field1": "Error details for field1",
"field2": "Error details for field2"
},
"timestamp": "ISO-8601 timestamp",
"requestId": "Unique request identifier"
}

Error Categories​

4xx Client Errors​

400 Bad Request​

  • Code: INVALID_REQUEST
  • Description: The request was malformed or contains invalid parameters
  • Example:
    {
    "status": "error",
    "code": "INVALID_REQUEST",
    "message": "Invalid request parameters",
    "details": {
    "email": "Must be a valid email address",
    "age": "Must be a positive number"
    }
    }

401 Unauthorized​

  • Code: UNAUTHORIZED
  • Description: Authentication is required or provided credentials are invalid
  • Example:
    {
    "status": "error",
    "code": "UNAUTHORIZED",
    "message": "Invalid or expired authentication token"
    }

403 Forbidden​

  • Code: FORBIDDEN
  • Description: The authenticated user lacks required permissions
  • Example:
    {
    "status": "error",
    "code": "FORBIDDEN",
    "message": "Insufficient permissions to access this resource"
    }

404 Not Found​

  • Code: NOT_FOUND
  • Description: The requested resource does not exist
  • Example:
    {
    "status": "error",
    "code": "NOT_FOUND",
    "message": "Resource with ID '123' not found"
    }

5xx Server Errors​

500 Internal Server Error​

  • Code: INTERNAL_ERROR
  • Description: An unexpected error occurred on the server
  • Example:
    {
    "status": "error",
    "code": "INTERNAL_ERROR",
    "message": "An unexpected error occurred",
    "requestId": "req_123abc"
    }

503 Service Unavailable​

  • Code: SERVICE_UNAVAILABLE
  • Description: The service is temporarily unavailable
  • Example:
    {
    "status": "error",
    "code": "SERVICE_UNAVAILABLE",
    "message": "Service is undergoing maintenance"
    }

Error Handling Guidelines​

Client-Side Error Handling​

try {
const response = await api.getData();
// Handle success
} catch (error) {
if (error.code === 'UNAUTHORIZED') {
// Handle authentication error
redirectToLogin();
} else if (error.code === 'NOT_FOUND') {
// Handle not found error
showNotFoundMessage();
} else {
// Handle other errors
showErrorMessage(error.message);
}
}

Server-Side Error Handling​

try {
const data = await processRequest();
return successResponse(data);
} catch (error) {
if (error instanceof ValidationError) {
return errorResponse({
status: 400,
code: 'INVALID_REQUEST',
message: 'Validation failed',
details: error.details
});
}

// Log unexpected errors
logger.error('Unexpected error', {
error,
requestId: context.requestId
});

return errorResponse({
status: 500,
code: 'INTERNAL_ERROR',
message: 'An unexpected error occurred',
requestId: context.requestId
});
}

Error Logging​

Required Information​

  • Error code
  • Stack trace
  • Request context
  • User context
  • System state
  • Timestamp

Log Format​

{
"level": "error",
"timestamp": "2025-02-04T06:28:28+05:30",
"requestId": "req-123",
"userId": "user-456",
"error": {
"code": "AUTH_ERROR",
"message": "Invalid token provided",
"stack": "...",
"details": {}
},
"context": {
"service": "auth-service",
"operation": "verify-token",
"environment": "production"
}
}

Error Recovery​

Retry Strategy​

const retryOperation = async (
operation: () => Promise<any>,
maxRetries: number = 3,
delay: number = 1000
): Promise<any> => {
let lastError: Error;

for (let i = 0; i < maxRetries; i++) {
try {
return await operation();
} catch (error) {
lastError = error;
await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, i)));
}
}

throw lastError;
};

Circuit Breaker​

class CircuitBreaker {
private failures: number = 0;
private lastFailure: number = 0;
private readonly threshold: number = 5;
private readonly resetTimeout: number = 60000;

async execute(operation: () => Promise<any>): Promise<any> {
if (this.isOpen()) {
throw new Error('Circuit breaker is open');
}

try {
const result = await operation();
this.reset();
return result;
} catch (error) {
this.recordFailure();
throw error;
}
}

private isOpen(): boolean {
if (this.failures >= this.threshold) {
const now = Date.now();
if (now - this.lastFailure >= this.resetTimeout) {
this.reset();
return false;
}
return true;
}
return false;
}

private recordFailure(): void {
this.failures++;
this.lastFailure = Date.now();
}

private reset(): void {
this.failures = 0;
this.lastFailure = 0;
}
}
  • API Documentation Template
  • Logging Standards
  • Monitoring Guide
  • Incident Response Plan

Usage Guide​

When to Use​

  • Implementing new API endpoints
  • Adding error handling to existing code
  • Documenting error responses
  • Creating client-side error handlers

Best Practices​

  1. Error Response Format

    • Use consistent structure
    • Include error codes
    • Provide clear messages
    • Add helpful details
  2. Error Codes

    • Use descriptive codes
    • Group by category
    • Be consistent
    • Document all codes
  3. Error Messages

    • Use clear language
    • Be specific
    • Include actionable info
    • Avoid technical jargon
  4. Security

    • Hide sensitive details
    • Log appropriately
    • Sanitize output
    • Handle all cases

Example​

# Authentication Error Handling

## Error Response Format

### Invalid Credentials
```json
{
"status": "error",
"code": "INVALID_CREDENTIALS",
"message": "The provided email or password is incorrect",
"timestamp": "2024-02-04T12:00:00Z",
"requestId": "auth_123abc"
}

Account Locked​

{
"status": "error",
"code": "ACCOUNT_LOCKED",
"message": "Account has been locked due to multiple failed attempts",
"details": {
"remainingTime": "30 minutes",
"attempts": 5,
"maxAttempts": 5
},
"timestamp": "2024-02-04T12:00:00Z",
"requestId": "auth_456def"
}

Error Handling Code​

Client-Side​

async function handleLogin(credentials: LoginCredentials) {
try {
const response = await authApi.login(credentials);
return response.data;
} catch (error) {
switch (error.code) {
case 'INVALID_CREDENTIALS':
showError('Invalid email or password');
break;
case 'ACCOUNT_LOCKED':
showError(`Account locked. Try again in ${error.details.remainingTime}`);
break;
default:
showError('An unexpected error occurred');
}
throw error;
}
}

Server-Side​

async function handleLoginRequest(req: Request, res: Response) {
try {
const { email, password } = req.body;

// Validate input
if (!email || !password) {
return res.status(400).json({
status: 'error',
code: 'INVALID_REQUEST',
message: 'Email and password are required'
});
}

// Check login attempts
if (await isAccountLocked(email)) {
return res.status(403).json({
status: 'error',
code: 'ACCOUNT_LOCKED',
message: 'Account is locked',
details: await getLockoutDetails(email)
});
}

// Attempt login
const user = await authenticateUser(email, password);
if (!user) {
await incrementFailedAttempts(email);
return res.status(401).json({
status: 'error',
code: 'INVALID_CREDENTIALS',
message: 'Invalid email or password'
});
}

// Success
await resetFailedAttempts(email);
return res.json({
status: 'success',
data: {
token: generateToken(user),
user: sanitizeUser(user)
}
});
} catch (error) {
logger.error('Login error', { error, email });
return res.status(500).json({
status: 'error',
code: 'INTERNAL_ERROR',
message: 'An unexpected error occurred'
});
}
}