Best practices for using Sentry SDK in TypeScript and Python.
Use when implementing structured error context with scopes, breadcrumb
strategies, beforeSend/beforeBreadcrumb filtering, custom fingerprinting,
user context, or performance span creation.
Trigger: "sentry best practices", "sentry patterns", "sentry sdk usage",
"sentry scope", "sentry breadcrumbs", "sentry beforeSend", "sentry fingerprint".
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Best practices for using Sentry SDK in TypeScript and Python.
Use when implementing structured error context with scopes, breadcrumb
strategies, beforeSend/beforeBreadcrumb filtering, custom fingerprinting,
user context, or performance span creation.
Trigger: "sentry best practices", "sentry patterns", "sentry sdk usage",
"sentry scope", "sentry breadcrumbs", "sentry beforeSend", "sentry fingerprint".
Designed for Claude Code, also compatible with Codex and OpenClaw
Sentry SDK Patterns
Overview
Production patterns for @sentry/node (v8+) and sentry-sdk (Python 2.x+) covering scoped error context, breadcrumb strategies, event filtering with beforeSend, custom fingerprinting for issue grouping, and performance instrumentation with spans. All examples use real Sentry SDK APIs.
Prerequisites
Sentry SDK v8+ installed (@sentry/node, @sentry/react, or sentry-sdk)
SENTRY_DSN environment variable configured
Familiarity with async/await (TypeScript) or context managers (Python)
Instructions
Step 1 -- Structured Error Context with Scopes
Use Sentry.withScope() (TypeScript) or sentry_sdk.new_scope() (Python) to attach context to individual events without leaking state across requests.
import sentry_sdk
defcapture_error(error, severity="error", tags=None, context=None, user=None):
"""Capture exception with isolated scope context."""with sentry_sdk.new_scope() as scope:
scope.set_level(severity)
if tags:
for key, value in tags.items():
scope.set_tag(key, value)
if context:
scope.set_context("app", context)
if user:
scope.set_user(user)
sentry_sdk.capture_exception(error)
Key rule: Never call Sentry.setTag() or sentry_sdk.set_tag() at the module level inside request handlers. Those mutate the global scope and leak between concurrent requests. Always use withScope() or new_scope().
Step 2 -- Breadcrumbs, Filtering, and Fingerprints
Override default stack-trace grouping when the same root cause produces different stacks:
Sentry.withScope((scope) => {
// Group all payment gateway timeouts together
scope.setFingerprint(['payment-gateway-timeout', gatewayName]);
Sentry.captureException(error);
});
with sentry_sdk.new_scope() as scope:
scope.fingerprint = ["payment-gateway-timeout", gateway_name]
sentry_sdk.capture_exception(error)
Step 3 -- Framework Integration and Performance Spans
See implementation.md for Django middleware, test mocking patterns, and additional framework examples.
Output
After applying these patterns you will have:
Centralized error handler module with typed severity and scoped context
Structured breadcrumb helpers for auth, db, and http events
beforeSend filter that drops noise and scrubs PII
beforeBreadcrumb callback that redacts sensitive query parameters
Custom fingerprinting for accurate issue grouping
Framework error boundaries for Express and React
Performance spans for tracing critical code paths
Error Handling
Error
Cause
Solution
Scope leaking between requests
Global scope mutations in async handlers
Use withScope() / new_scope() for per-event context
Duplicate events
Error caught and re-thrown at two layers
Capture at one level only -- middleware or handler, not both
Missing breadcrumbs
Cleared after max count (default 100)
Set maxBreadcrumbs in Sentry.init()
beforeSend returns undefined
Missing return statement
Always return event or null explicitly
Events grouped incorrectly
Default stack-trace fingerprinting
Use scope.setFingerprint() with semantic keys
Sentry is not defined
SDK not imported
Verify import * as Sentry from '@sentry/node'
Spans not appearing
Missing tracing config
Set tracesSampleRate in Sentry.init()
Examples
Centralized error handler: Create lib/error-handler.ts wrapping Sentry.withScope() with typed severity, tags, context, user, and fingerprint support.
Breadcrumb trail for checkout: Add breadcrumb.auth('login'), breadcrumb.db('SELECT', 'orders'), breadcrumb.http('POST', '/api/payments', 201) before critical operations so errors include full context timeline.
Noise filtering: Configure beforeSend to drop ResizeObserver loop and Network request failed, scrub PII from user context and cookies.
Fix issue grouping: Add scope.setFingerprint(['payment-gateway-timeout', gatewayName]) to group all payment timeouts by gateway.
See examples.md for full worked scenarios with Python context managers and async wrappers.