Error Handling and Logging - pacificnm/wiki-ai GitHub Wiki

Error Handling and Logging System

This document describes the comprehensive error handling and logging system implemented in the wiki-ai project.

Overview

The error handling system consists of several components working together to provide robust error management for both frontend and backend:

  • Backend Logger: Winston-based logging system with multiple transports
  • Backend Error Handling: Custom error classes and middleware for consistent error responses
  • Frontend Error Boundary: React Error Boundary for catching and displaying user-friendly errors
  • Frontend Error Hooks: Custom React hooks for handling API errors and user notifications
  • Error Reporting: Client-side error logging to server endpoint

Backend Components

1. Logger Middleware (server/middleware/logger.js)

Winston-based logger with the following features:

  • Console and file logging
  • Configurable log levels
  • Request-scoped logging
  • HTTP request logging via Morgan
  • Structured logging format

Usage:

import { logger } from './middleware/logger.js';

logger.info('Operation completed');
logger.error('Operation failed', { error: error.message });
logger.warn('Warning message', { userId: 'user123' });

2. Error Handling Middleware (server/middleware/error.js)

Comprehensive error handling system with:

  • Custom error classes (AppError, ValidationError, AuthenticationError, etc.)
  • Global error handler middleware
  • Async error wrapper
  • Development vs production error responses

Custom Error Classes:

  • AppError: Base application error class
  • ValidationError: Data validation errors
  • AuthenticationError: Authentication failures
  • AuthorizationError: Permission errors
  • NotFoundError: Resource not found
  • ConflictError: Data conflicts
  • RateLimitError: Rate limiting errors

Usage:

import { AppError, asyncHandler } from './middleware/error.js';

// Throw custom error
throw new AppError('User not found', 404, 'NOT_FOUND');

// Wrap async route handlers
router.get('/users', asyncHandler(async (req, res) => {
  const users = await User.find();
  res.json(users);
}));

3. Error Controller (server/controllers/errorController.js)

Handles client-side error reporting with:

  • Error validation using Zod schemas
  • Structured error logging
  • Error statistics (for admin users)
  • Error log cleanup utilities

API Endpoints:

  • POST /api/errors - Log client-side errors
  • GET /api/errors/stats - Get error statistics (admin)
  • DELETE /api/errors/cleanup - Clean old error logs (admin)
  • GET /api/errors/test - Test error scenarios (development only)

4. Error Routes (server/routes/errorRoutes.js)

Express routes for error handling endpoints with proper authentication and validation.

Frontend Components

1. Error Boundary (client/components/ErrorBoundary.jsx)

React Error Boundary component with:

  • Catches JavaScript errors in component tree
  • Displays user-friendly error messages
  • Categorizes errors (network, rendering, data, unknown)
  • Logs errors to server endpoint
  • Retry mechanisms
  • Material-UI design integration

Usage:

import ErrorBoundary from './components/ErrorBoundary';

function App() {
  return (
    <ErrorBoundary>
      <YourAppComponents />
    </ErrorBoundary>
  );
}

2. Error Handling Hooks (client/hooks/useError.js)

Custom React hooks for error management:

useError() Hook:

  • Display error messages to users via Snackbar
  • Handle different error types
  • Clear errors
  • Async operation wrapper

useApiError() Hook:

  • Handle API response errors
  • Parse HTTP status codes
  • Convert technical errors to user-friendly messages

Usage:

import { useError, useApiError } from './hooks/useError';

function MyComponent() {
  const { showError, showSuccess } = useError();
  const { handleApiError } = useApiError();

  const handleSubmit = async () => {
    try {
      const result = await api.submitData();
      showSuccess('Data submitted successfully!');
    } catch (error) {
      handleApiError(error, 'Submit data');
    }
  };
}

Error Reporting Flow

Client-Side Error Reporting

  1. JavaScript Errors: Caught by useError hook and logged to server
  2. React Errors: Caught by ErrorBoundary component and logged to server
  3. API Errors: Handled by useApiError hook with user notifications

Server-Side Error Logging

  1. Error Validation: Incoming errors validated with Zod schemas
  2. Structured Logging: Errors logged with Winston in structured format
  3. Error Storage: Logged to files and console (can be extended to databases)
  4. Error Monitoring: Ready for integration with monitoring services

Configuration

Environment Variables

# Logging
LOG_LEVEL=info
LOG_DIR=./logs

# Error Handling
NODE_ENV=development

Log Files

Logs are stored in the following files:

  • logs/error.log - Error-level logs only
  • logs/combined.log - All log levels
  • Console output for development

Integration with Monitoring Services

The system is designed to integrate with external monitoring services:

Supported Services

  • Sentry: For error tracking and performance monitoring
  • LogRocket: For session replay and error tracking
  • Bugsnag: For error monitoring
  • Datadog: For application monitoring
  • New Relic: For application performance monitoring

Integration Points

  1. Client-side: Update sendToErrorService in useError.js
  2. Server-side: Add transport to Winston logger configuration
  3. Error Controller: Extend to send to external APIs

Best Practices

Frontend

  1. Wrap Components: Always wrap your app with ErrorBoundary
  2. Use Hooks: Use useError and useApiError hooks for consistent error handling
  3. User-Friendly Messages: Convert technical errors to user-friendly messages
  4. Don't Spam: Avoid showing multiple error messages for the same issue

Backend

  1. Use Custom Errors: Use custom error classes instead of generic Error
  2. Async Wrappers: Always wrap async route handlers with asyncHandler
  3. Structured Logging: Use structured logging with relevant context
  4. Error Codes: Use consistent error codes for client-side handling

General

  1. Log Context: Always include relevant context in error logs
  2. Rate Limiting: Implement rate limiting for error reporting endpoints
  3. Privacy: Don't log sensitive information (passwords, tokens)
  4. Monitoring: Set up alerts for error rate thresholds

Testing Error Handling

Development Testing

Use the test endpoint to simulate different error types:

# Test different error types
GET /api/errors/test?type=error
GET /api/errors/test?type=validation
GET /api/errors/test?type=auth
GET /api/errors/test?type=server

Frontend Testing

// Test Error Boundary
const TestError = () => {
  throw new Error('Test error for boundary');
};

// Test useError hook
const { showError } = useError();
showError('Test error message');

Troubleshooting

Common Issues

  1. Logs not appearing: Check LOG_LEVEL environment variable
  2. Client errors not reaching server: Check network and authentication
  3. Error boundary not catching: Ensure it wraps the component tree
  4. Infinite error loops: Check error logging doesn't cause more errors

Debug Mode

Set NODE_ENV=development for:

  • Detailed error messages
  • Stack traces in responses
  • Additional logging
  • Test endpoints enabled

Future Enhancements

  1. Error Aggregation: Implement error aggregation to prevent spam
  2. User Feedback: Add user feedback collection on errors
  3. Error Analytics: Implement error analytics dashboard
  4. Performance Monitoring: Add performance error detection
  5. Mobile Support: Extend error handling for mobile applications