Core Features
Error Tracking
How Reliable captures, groups, enriches, and de-duplicates errors — both automatic and manual.
Automatic capture#
With captureErrors: true (the default), Reliable installs two listeners:
window.addEventListener('error')— uncaught synchronous errors and resource load failures.window.addEventListener('unhandledrejection')— Promise rejections that no.catch()handled.
Both listeners normalize the thrown value into a common shape, fingerprint it, attach context, and send a POST /errors request.
What gets attached to every error#
| Name | Type | Default | Description |
|---|---|---|---|
| fingerprint | string | — | Stable hash of (message + first stack frame). Used to group identical errors on the backend. |
| stack_trace | string | — | The raw stack from error.stack. Source-map resolution happens server-side. |
| trigger | enum | — | page_load, click, navigation, api_response, timer, or unknown — heuristic for what *caused* the error. |
| is_crash | boolean | — | True for unrecoverable errors: React error boundaries, ChunkLoadError, hydration failures. |
| severity | enum | — | low | medium | high | critical. Crashes are critical; unhandled rejections are high; everything else is medium. |
| router_history | array | — | The last 10 route changes the user made before the error. |
| browser_state | object | — | Cookies + localStorage at the time of the error (with sensitive keys redacted). |
| breadcrumbs | array | — | The last 30 breadcrumbs — clicks, navigations, console logs, manual additions. |
| tags | object | — | Per-event tags from captureException options, merged over scope tags from setTag/setTags. |
| component_stack | string | — | Set by the React error boundary. Identifies which component crashed in the React tree. |
De-duplication#
Errors with the same fingerprint within a 5-second window are dropped client-side. This stops render-loop floods (an error in a render that retriggers itself) from saturating the queue and racking up cost. The first error in a burst is always sent — you'll never miss the initial signal.
Manual capture#
For caught errors, soft failures, or any error path you handle yourself, use captureException:
import { captureException } from '@reliableapp/frontend-core';
try {
await chargeCustomer(amount);
} catch (err) {
captureException(err, {
severity: 'high',
isCrash: false,
tags: {
flow: 'checkout',
payment_provider: 'stripe',
amount_usd: String(amount),
},
});
showRetryDialog();
}captureException works with any thrown value, not just Error instances:
captureException('user clicked submit twice'); // string
captureException({ code: 'EBADCSRF', detail: '…' }); // POJO
captureException(new TypeError('expected number')); // ErrorStrings and POJOs are normalized into a synthetic Error internally so the backend can still group and replay them properly.
captureMessage for non-error events#
Sometimes you want to report something that isn't an exception — a soft failure, a retry that succeeded, a state transition worth knowing about.
import { captureMessage } from '@reliableapp/frontend-core';
if (retryCount > 0) {
captureMessage('payment retry succeeded', {
severity: 'low',
tags: { retry_count: String(retryCount) },
});
}Severity levels#
| Name | Type | Default | Description |
|---|---|---|---|
| low | string | — | Soft signals — retries, recoverable errors, noteworthy state. Don't page anyone. |
| medium | string | — | Default for caught exceptions. Worth attention but not urgent. |
| high | string | — | Unhandled rejections, payment failures, anything that hurts a user. |
| critical | string | — | Crashes — React error boundary, chunk load failure, hydration failure. Page someone. |
Return value#
Both captureException and captureMessage return a UUID string (the event ID) or null if the event was dropped (SDK not initialized, de-duped, or filtered by beforeSend).
const eventId = captureException(err);
if (eventId) {
console.log('Reported as event', eventId);
// Show user a "report this with ID xyz" dialog
}React error boundaries
<ReliableErrorBoundary>. It catches render-phase crashes and reports them with the full React component stack — see React → Error Boundary.