Skip to content

Error Handling

Cameron Rye edited this page Nov 19, 2025 · 1 revision

Error Handling Strategy

Overview

DosKit implements a comprehensive, multi-layered error handling strategy to ensure a robust user experience and facilitate debugging.

Error Handling Layers

  1. Global Error Handler - Captures uncaught errors and unhandled promise rejections
  2. React Error Boundaries - Catches React component errors
  3. Component-Level Error States - Local error handling in components
  4. Error Tracking Service - Centralized error reporting and monitoring
  5. User-Friendly Error Messages - Maps technical errors to readable messages

Components

1. Global Error Handler

File: src/utils/globalErrorHandler.ts

Purpose: Captures all uncaught errors and unhandled promise rejections at the window level.

Features:

  • Captures window.onerror events
  • Captures window.onunhandledrejection events
  • Filters out known harmless errors (fullscreen API, keyboard lock, etc.)
  • Provides error context (browser info, timestamp, user action)
  • Integrates with error tracking service

Usage:

import { initializeGlobalErrorHandler } from './utils/globalErrorHandler';

initializeGlobalErrorHandler({
  showUserFriendlyErrors: true,
  suppressHarmlessErrors: true,
  onError: (error, context) => {
    console.error('Error captured:', error, context);
  },
});

2. Error Tracking Service

File: src/utils/errorTracking.ts

Purpose: Abstraction layer for error tracking services (Sentry, LogRocket, etc.)

Features:

  • Service-agnostic interface
  • Console tracker for development
  • Sentry tracker placeholder for production
  • Error severity levels (DEBUG, INFO, WARNING, ERROR, FATAL)
  • Error context tracking
  • Breadcrumb support for user action trails

Usage:

import { initializeErrorTracking, getErrorTracker, ErrorSeverity } from './utils/errorTracking';

// Initialize (in main.tsx)
initializeErrorTracking('console'); // or 'sentry' with config

// Use in code
const tracker = getErrorTracker();
tracker.captureError(error, { userAction: 'Loading app' }, ErrorSeverity.ERROR);
tracker.addBreadcrumb('User clicked load button', 'user-action');

3. Error Boundary

File: src/components/ErrorBoundary.tsx

Purpose: Catches React component errors and prevents full app crashes

Features:

  • Catches errors in React component tree
  • Displays fallback UI with error details (dev mode)
  • Integrates with error tracking service
  • Provides reset functionality

Usage:

import { ErrorBoundary } from './components/ErrorBoundary';

<ErrorBoundary>
  <App />
</ErrorBoundary>

4. User-Friendly Error Messages

File: src/utils/errorMessages.ts

Purpose: Maps technical errors to user-friendly messages

Features:

  • Pattern matching for common errors
  • Provides suggestions for resolution
  • Includes original error in dev mode
  • Extensible error mappings

Usage:

import { getUserFriendlyError } from './utils/errorMessages';

try {
  await fetchData();
} catch (error) {
  const friendly = getUserFriendlyError(error);
  console.error(friendly.message);
  if (friendly.suggestion) {
    console.info(friendly.suggestion);
  }
}

Error Flow

Uncaught Error Flow

Error occurs
  ↓
Global Error Handler captures
  ↓
Check if harmless → Suppress if yes
  ↓
Log to console (logger)
  ↓
Track with error tracking service
  ↓
Show user-friendly message (if enabled)

React Error Flow

Error in React component
  ↓
Error Boundary catches
  ↓
Update state (hasError = true)
  ↓
Track with error tracking service
  ↓
Render fallback UI

Best Practices

1. Always Use Try/Catch for Async Operations

const handleLoadApp = async () => {
  try {
    await loadApp();
  } catch (error) {
    const friendly = getUserFriendlyError(error);
    setError(friendly.message);
    getErrorTracker().captureError(error, { userAction: 'Loading app' });
  }
};

2. Add Context to Errors

tracker.captureError(error, {
  userAction: 'Loading Second Reality demo',
  component: 'DemoSelector',
  metadata: { appId: 'second-reality' },
});

3. Use Breadcrumbs for User Actions

tracker.addBreadcrumb('User selected app', 'user-action', { appId: 'doom' });

4. Wrap Critical Components with Error Boundaries

<ErrorBoundary>
  <DosPlayer />
</ErrorBoundary>

Related Documentation


Made with ❤️ by Cameron Rye

Clone this wiki locally