Sentry - Error Capturing & Context
Capture errors and enrich them with context for better debugging.
Capturing Errors
Manual Error Capture
import * as Sentry from "@sentry/browser";
try { riskyOperation(); } catch (error) { Sentry.captureException(error); }
Capture with Extra Context
Sentry.captureException(error, { tags: { section: "checkout", feature: "payment", }, extra: { orderId: order.id, cartItems: cart.items.length, }, level: "error", });
Capture Messages
Sentry.captureMessage("User exceeded rate limit", { level: "warning", tags: { userId: user.id }, });
Adding Context
User Context
Sentry.setUser({ id: user.id, email: user.email, username: user.username, ip_address: "{{auto}}", });
// Clear on logout Sentry.setUser(null);
Tags
// Global tags Sentry.setTag("app.version", "1.2.3"); Sentry.setTag("tenant", customer.tenantId);
// Per-event tags Sentry.captureException(error, { tags: { operation: "database_query" }, });
Extra Data
Sentry.setExtra("orderDetails", { items: order.items, total: order.total, });
Context Objects
Sentry.setContext("order", { id: order.id, status: order.status, items: order.items.length, });
Sentry.setContext("customer", { plan: customer.plan, region: customer.region, });
Breadcrumbs
Automatic Breadcrumbs
// Most integrations add breadcrumbs automatically // Console, fetch, XHR, DOM events, navigation
Manual Breadcrumbs
Sentry.addBreadcrumb({ category: "auth", message: "User logged in", level: "info", data: { userId: user.id, method: "oauth", }, });
Configure Breadcrumbs
Sentry.init({ beforeBreadcrumb(breadcrumb, hint) { // Filter or modify breadcrumbs if (breadcrumb.category === "console") { return null; // Don't capture console logs } return breadcrumb; }, maxBreadcrumbs: 50, });
Error Boundaries (React)
import * as Sentry from "@sentry/react";
// Basic error boundary const App = () => ( <Sentry.ErrorBoundary fallback={<ErrorPage />}> <YourApp /> </Sentry.ErrorBoundary> );
// With custom fallback and onError <Sentry.ErrorBoundary fallback={({ error, resetError }) => ( <div> <p>Something went wrong: {error.message}</p> <button onClick={resetError}>Try again</button> </div> )} onError={(error, componentStack) => { console.error("Caught by Sentry boundary:", error); }} beforeCapture={(scope) => { scope.setTag("location", "checkout"); }}
<CheckoutFlow /> </Sentry.ErrorBoundary>
Fingerprinting
Custom Grouping
Sentry.captureException(error, { fingerprint: ["{{ default }}", user.id], });
Override Default Grouping
Sentry.init({ beforeSend(event) { if (event.exception?.values?.[0]?.type === "ChunkLoadError") { event.fingerprint = ["chunk-load-error"]; } return event; }, });
Scopes
Configure Scope
Sentry.configureScope((scope) => { scope.setUser({ id: user.id }); scope.setTag("theme", "dark"); scope.setLevel("warning"); });
With Scope (Isolated)
Sentry.withScope((scope) => { scope.setTag("operation", "batch_import"); scope.setExtra("batchSize", items.length); Sentry.captureException(error); }); // Tags/extra only apply within this scope
Best Practices
-
Set user context on login, clear on logout
-
Add relevant business context (order ID, tenant, etc.)
-
Use tags for filterable, indexable data
-
Use extra for detailed debugging data
-
Implement error boundaries at feature boundaries
-
Use fingerprinting to group related errors
-
Add breadcrumbs for critical user actions