books/docs/architecture/error-handling-strategy.md
Greg fa8acef423 Epic 1, Story 1.1: Project Initialization & Repository Setup
- Initialize Git repository with main branch
- Create comprehensive .gitignore for Node.js, React, and environment files
- Set up directory structure (frontend/, backend/, docs/)
- Create detailed README.md with project overview and setup instructions
- Add .env.example with all required environment variables
- Configure Prettier for consistent code formatting

All acceptance criteria met:
 Git repository initialized with appropriate .gitignore
 Directory structure matches Technical Assumptions
 README.md created with project overview and setup docs
 .env.example file with all required environment variables
 Prettier config files added for code formatting consistency

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 15:12:30 +01:00

162 lines
3.8 KiB
Markdown

# Error Handling Strategy
## Error Flow
```mermaid
sequenceDiagram
participant User
participant FE as Frontend
participant API as Backend API
participant DB as Database
User->>FE: Submit invalid form
FE->>FE: Validate input
FE->>User: Show validation error (inline)
User->>FE: Submit valid form
FE->>API: POST request
API->>API: Validate input (express-validator)
alt Validation fails
API-->>FE: 400 Bad Request {error, details}
FE->>User: Display error message
else Validation passes
API->>DB: Query/mutation
alt Database error
DB-->>API: Error
API->>API: Log error
API-->>FE: 500 Server Error {error}
FE->>User: Display generic error
else Success
DB-->>API: Data
API-->>FE: 200/201 Success {data}
FE->>User: Display success message
end
end
```
## Error Response Format
```typescript
// Consistent error format across all API endpoints
interface ApiError {
error: string; // Human-readable error message
details?: Record<string, any>; // Optional validation details
timestamp?: string; // ISO timestamp
requestId?: string; // For debugging (optional)
}
// Examples:
// Validation error
{
"error": "Validation failed",
"details": {
"field": "deadlineDate",
"message": "Deadline must be in the future"
}
}
// Generic server error
{
"error": "Internal server error"
}
// Not found error
{
"error": "Book not found"
}
```
## Frontend Error Handling
```typescript
// services/api.js - Global error handler
async request(endpoint, options = {}) {
try {
const response = await fetch(`${API_BASE_URL}${endpoint}`, options);
if (!response.ok) {
const errorData = await response.json();
throw new ApiError(errorData.error, errorData.details, response.status);
}
return await response.json();
} catch (error) {
if (error instanceof ApiError) {
throw error; // Re-throw API errors
}
// Network errors or other fetch failures
throw new ApiError('Network error. Please check your connection.');
}
}
// Custom error class
class ApiError extends Error {
constructor(message, details, statusCode) {
super(message);
this.name = 'ApiError';
this.details = details;
this.statusCode = statusCode;
}
}
// Component error handling
try {
await booksService.addBook(bookData);
showSuccessMessage('Book added successfully!');
} catch (error) {
if (error instanceof ApiError) {
if (error.details) {
// Show field-specific errors
setFieldError(error.details.field, error.details.message);
} else {
// Show generic error
showErrorMessage(error.message);
}
} else {
showErrorMessage('An unexpected error occurred');
}
}
```
## Backend Error Handling
```typescript
// middleware/errorHandler.js - Centralized error handler
module.exports = (err, req, res, next) => {
// Log error for debugging
console.error('Error:', err);
// Prisma errors
if (err.code && err.code.startsWith('P')) {
if (err.code === 'P2025') {
return res.status(404).json({ error: 'Resource not found' });
}
if (err.code === 'P2002') {
return res.status(400).json({
error: 'Duplicate entry',
details: { field: err.meta?.target?.[0] }
});
}
return res.status(500).json({ error: 'Database error' });
}
// Validation errors (from express-validator)
if (err.errors && Array.isArray(err.errors)) {
return res.status(400).json({
error: 'Validation failed',
details: err.errors,
});
}
// Default: Internal server error
res.status(err.statusCode || 500).json({
error: err.message || 'Internal server error',
});
};
// Usage in server.js
app.use(errorHandler);
```
---