Skip to main content

Error Capture

The react and react-native packages ship error capture out of the box — no third-party bridge needed. Everything emits $error events through the consent-gated capture() pipeline and runs through PiiSanitizer automatically.

Manual capture (captureException)​

captureException lives in core and is re-exported from both framework packages:

import { captureException } from '@drakkar.software/sunglasses-react'; // or -react-native

try {
doRiskyThing();
} catch (err) {
captureException(client, err); // $error_handled: true
}

Options​

captureException(client, err, {
handled: true, // false for unhandled errors — default true
level: 'error', // Sentry-compatible severity
includeStack: true, // include $error_stack — on by default
maxStackFrames: 5, // number of frames to include
maxMessageLength: 200, // truncate messages — they can contain PII
ignorePatterns: [/ResizeObserver/],
properties: { screen: 'Checkout' },
beforeCapture: (props) => ({ ...props, app_version: '1.2.0' }), // transform or drop (null)
});

What gets captured automatically​

Beyond message and type, captureException extracts:

FieldWhat it captures
$error_stackParsed stack frames (V8 and Hermes formats)
$error_causeerror.cause chain — serialized as "Name: msg\ncaused by: …"
$error_extraCustom scalar properties on the Error (code, statusCode, etc.)
$error_sourceOrigin tag set by the capture path (see below)
$error_fatalReact Native isFatal flag from ErrorUtils
$error_component_stackReact component stack from error boundaries
$error_filename/line/columnSource location from web ErrorEvent

See Event Shape → $error properties for the full type.

Error boundary (render-phase errors)​

SunglassesErrorBoundary catches render-phase errors with $error_handled: true and automatically captures the React component stack ($error_component_stack) from errorInfo:

import { SunglassesProvider, SunglassesErrorBoundary } from '@drakkar.software/sunglasses-react';

<SunglassesProvider client={client}>
<SunglassesErrorBoundary fallback={<ErrorPage />}>
<App />
</SunglassesErrorBoundary>
</SunglassesProvider>

Captured event will have $error_source: 'boundary' and $error_component_stack showing the React tree at the time of the crash.

Global error autocapture (opt-in)​

<SunglassesProvider client={client} autoCaptureErrors>
<App />
</SunglassesProvider>

On web: listens to window 'error' (sets $error_source: 'global' + filename/line/column) and 'unhandledrejection' ($error_source: 'rejection'). On RN: chains ErrorUtils ($error_source: 'global', $error_fatal: isFatal).

To disable the stack or restrict patterns:

<SunglassesProvider
client={client}
autoCaptureErrors={{ includeStack: false, ignorePatterns: [/Network request failed/] }}
>
warning

Error boundaries do not catch errors in event handlers or async code — use captureException there.

Console capture (opt-in)​

<SunglassesProvider client={client} autoCaptureErrors={{ console: true }}>
<App />
</SunglassesProvider>

Console-captured events carry $error_source: 'console'. Console capture is noisy — React logs render errors and warnings through console.error. Use ignorePatterns to filter.

You can also patch directly:

import { patchConsole } from '@drakkar.software/sunglasses-react';
const unpatch = patchConsole(client, { levels: ['error', 'warn'] });
// ... later: unpatch();

Full coverage pattern​

Combine all three:

  1. Error boundary — render errors ($error_handled: true, $error_source: 'boundary', with component stack)
  2. autoCaptureErrors — global/unhandled errors ($error_handled: false, $error_source: 'global' / 'rejection')
  3. captureException — try/catch in event handlers and async code

Privacy and stacks​

Stack traces are on by default (includeStack: true). They may expose internal file paths and function names. Set includeStack: false if your privacy policy prohibits this. PII inside stack frames is masked (not whole-value-dropped) — see PII Sanitization.