Thisbefine
API Reference

Error Types

When things go wrong, here's what we capture

Error Types

The structure of error events. Knowing this helps you understand what you'll see in the dashboard and what you can filter on.

ErrorPayload

The full structure of an error event.

interface ErrorPayload {
  message: string;
  stack?: string;
  type?: string;
  level: 'warning' | 'error' | 'fatal';
  fingerprint: string;
  url?: string;
  breadcrumbs?: Breadcrumb[];
  tags?: Record<string, string>;
  context?: Record<string, unknown>;
  timestamp?: string;
  anonymousId?: string;
  userId?: string;
  sessionId?: string;
}

Prop

Type

What a real error looks like:

{
  "message": "Cannot read property 'map' of undefined",
  "stack": "TypeError: Cannot read property 'map' of undefined\n    at ProductList (ProductList.tsx:42:15)\n    at renderWithHooks (react-dom.js:1234)",
  "type": "TypeError",
  "level": "error",
  "fingerprint": "a1b2c3d4",
  "url": "https://app.example.com/products",
  "breadcrumbs": [
    {
      "type": "navigation",
      "message": "Navigated to /products",
      "timestamp": "2025-01-15T10:29:55.000Z"
    },
    {
      "type": "click",
      "message": "Clicked on .filter-button",
      "timestamp": "2025-01-15T10:29:58.000Z"
    }
  ],
  "context": {
    "component": "ProductList",
    "filters": { "category": "electronics" }
  },
  "timestamp": "2025-01-15T10:30:00.000Z",
  "anonymousId": "anon_abc123",
  "userId": "user_456"
}

That's a lot of context. Way better than "Error: undefined".


A breadcrumb is something that happened before the error. It's the trail of events leading up to the crash.

interface Breadcrumb {
  type: 'click' | 'navigation' | 'network' | 'console' | 'custom';
  message: string;
  timestamp?: string;
  data?: Record<string, unknown>;
}

Prop

Type

TypeWhat It CapturesAuto-Captured?
clickUser clicks on elementsYes
navigationPage changes, pushState, popstateYes
networkFailed fetch/XHR requestsIf enabled
consoleconsole.error() callsIf enabled
customWhatever you add with addBreadcrumb()No (manual)

Auto-Captured Click Breadcrumb

{
  "type": "click",
  "message": "Clicked on button.submit-btn",
  "timestamp": "2025-01-15T10:29:58.000Z",
  "data": {
    "selector": "button.submit-btn",
    "text": "Submit"
  }
}

Auto-Captured Navigation Breadcrumb

{
  "type": "navigation",
  "message": "Navigated to /dashboard",
  "timestamp": "2025-01-15T10:29:55.000Z",
  "data": {
    "from": "/login",
    "to": "/dashboard"
  }
}

Manual Custom Breadcrumb

analytics.addBreadcrumb({
  type: 'custom',
  message: 'User started checkout',
  data: {
    cartItems: 3,
    total: 149.97,
  },
});

Error Levels

Pick the right level for the situation:

LevelWhen to Use
warningSomething's off but the app still works
errorSomething broke
fatalThe app crashed
// Warning - degraded but working
analytics.captureMessage(
  'API response slow (>2s)',
  'warning',
  { endpoint: '/api/users', duration: 2500 }
);

// Error - something broke
analytics.captureMessage(
  'Failed to load user preferences',
  'error',
  { userId: 'user_123' }
);

// Fatal - everything's on fire
analytics.captureMessage(
  'Database connection lost',
  'fatal',
  { reconnectAttempts: 5 }
);

Error Fingerprinting

Similar errors get grouped together using a fingerprint. The fingerprint is computed from:

  1. Error message (with dynamic values normalized)
  2. Top stack frame (file + function + line number)

This means you see "42 occurrences" instead of 42 separate errors.

Example grouping:

// Same fingerprint (same error, same location):
"Cannot read property 'name' of undefined" at ProductCard.tsx:42
"Cannot read property 'name' of undefined" at ProductCard.tsx:42

// Different fingerprints (different property):
"Cannot read property 'name' of undefined" at ProductCard.tsx:42
"Cannot read property 'price' of undefined" at ProductCard.tsx:42

What Gets Captured Automatically

When errors.enabled is true:

SourceCaptured?
throw new Error()Yes
Unhandled promise rejectionsYes
window.onerrorYes
console.error()Only if captureConsoleErrors: true
Failed fetch/XHROnly if captureNetworkErrors: true

Filtering Errors

Use beforeSend to keep your error list clean:

{
  errors: {
    enabled: true,
    beforeSend: (payload) => {
      // Browser extension errors aren't your problem
      if (payload.stack?.includes('chrome-extension://')) {
        return null;
      }

      // ResizeObserver loop errors are noisy and usually harmless
      if (payload.message.includes('ResizeObserver')) {
        return null;
      }

      // Third-party script errors with no stack trace
      if (payload.message === 'Script error.' && !payload.stack) {
        return null;
      }

      return payload;
    },
  },
}

Return null to drop the error. Return the payload (modified or not) to send it.

On this page