Context
Enrich errors with user info, tags, request data, and custom context for better debugging.
Overview
Context is additional information attached to errors that helps with debugging. It includes:
- User Context - Who experienced the error
- Tags - Key-value metadata for filtering
- Extra Data - Arbitrary debugging information
- Request Context - HTTP request details
- Device/OS Context - Environment information
User Context
Track which users are affected by errors:
Setting User Context
import { getObservability } from '@transactional/observability';
const obs = getObservability();
// Set user after authentication
obs.setUser({
id: user.id, // Required: unique identifier
email: user.email, // Optional
username: user.username, // Optional
name: user.displayName, // Optional
});Clearing User Context
// Clear on logout
obs.setUser(null);User Context on Capture
Override global user context per-error:
obs.captureException(error, {
user: {
id: 'user-456',
email: 'specific@example.com',
},
});User Count Tracking
When user context is set, issues track unique affected users:
Issue: "TypeError: Cannot read property 'name' of undefined"
├── Occurrences: 156
└── Users Affected: 23 ← Unique users
Tags
Tags are key-value pairs for filtering and searching errors:
Setting Global Tags
// Set tags that apply to all errors
obs.setTags({
environment: 'production',
version: '1.2.3',
region: 'us-east-1',
team: 'payments',
});Setting Tags on Capture
obs.captureException(error, {
tags: {
feature: 'checkout',
paymentProvider: 'stripe',
retryCount: '3',
},
});Common Tags
| Tag | Description | Example |
|---|---|---|
environment | Deploy environment | production, staging |
version | App version | 1.2.3 |
feature | Feature area | checkout, auth |
team | Owning team | payments, growth |
region | Server region | us-east-1 |
browser | Browser name | chrome, safari |
os | Operating system | windows, macos |
Tag Limits
| Limit | Value |
|---|---|
| Max tags per error | 50 |
| Max key length | 32 characters |
| Max value length | 200 characters |
Extra Data
Extra data is arbitrary JSON for debugging:
Setting Global Extra
obs.setExtra({
featureFlags: {
newCheckout: true,
darkMode: false,
},
abTests: {
pricing: 'variant-b',
},
});Setting Extra on Capture
obs.captureException(error, {
extra: {
orderId: order.id,
cartItems: cart.items,
totalAmount: cart.total,
paymentAttempts: 3,
lastError: previousError.message,
},
});Extra Data Best Practices
// Good - relevant debugging info
obs.captureException(error, {
extra: {
userId: user.id,
action: 'checkout',
cartTotal: 99.99,
},
});
// Bad - too much data, sensitive info
obs.captureException(error, {
extra: {
fullUserObject: user, // Too much
creditCardNumber: card.number, // Sensitive!
entireResponse: response, // Too large
},
});Extra Limits
| Limit | Value |
|---|---|
| Max extra size | 16 KB |
| Max depth | 10 levels |
| Max keys | 100 |
Request Context
Capture HTTP request details for server-side errors:
Automatic Request Context
For Express/Hono, request context is captured automatically:
// Express middleware
app.use((req, res, next) => {
const obs = getObservability();
obs.setRequestContext(req);
next();
});Manual Request Context
obs.captureException(error, {
request: {
url: request.url,
method: request.method,
headers: {
'content-type': request.headers['content-type'],
'user-agent': request.headers['user-agent'],
// Don't include Authorization header!
},
queryString: request.query,
data: request.body, // Sanitize sensitive fields
},
});Request Context Structure
interface RequestContext {
url?: string; // Full URL or path
method?: string; // HTTP method
headers?: Record<string, string>;
queryString?: string | Record<string, string>;
data?: unknown; // Request body
cookies?: Record<string, string>; // Sanitize!
env?: Record<string, string>; // Server env vars
}Sensitive Data Scrubbing
initObservability({
dsn: 'your-dsn',
enableErrorTracking: true,
// Headers to exclude
scrubHeaders: [
'Authorization',
'Cookie',
'X-API-Key',
],
// Body fields to scrub
scrubFields: [
'password',
'token',
'secret',
'creditCard',
],
});Device/OS Context
Environment information about the client:
Automatic Device Context
The SDK automatically captures:
{
device: {
name: 'iPhone 14 Pro',
family: 'iPhone',
model: 'iPhone14,2',
},
os: {
name: 'iOS',
version: '17.0',
},
browser: {
name: 'Safari',
version: '17.0',
},
runtime: {
name: 'node',
version: '20.0.0',
},
}Manual Device Context
obs.setContext('device', {
name: 'Custom Device',
model: 'Model X',
});
obs.setContext('os', {
name: 'CustomOS',
version: '1.0',
});Custom Contexts
Create custom context types for your application:
Setting Custom Contexts
// Set application-specific context
obs.setContext('subscription', {
plan: 'pro',
billingCycle: 'monthly',
trialEndsAt: '2024-02-15',
});
obs.setContext('organization', {
id: 'org-123',
name: 'Acme Corp',
tier: 'enterprise',
});
obs.setContext('feature', {
name: 'checkout-v2',
variant: 'treatment',
enabled: true,
});Context on Capture
obs.captureException(error, {
contexts: {
order: {
id: order.id,
status: order.status,
total: order.total,
},
payment: {
provider: 'stripe',
method: 'card',
last4: '4242',
},
},
});Environment and Release
Track deployment information:
Environment
initObservability({
dsn: 'your-dsn',
environment: process.env.NODE_ENV, // 'production', 'staging', 'development'
});Release
initObservability({
dsn: 'your-dsn',
release: `${process.env.APP_NAME}@${process.env.APP_VERSION}`,
// Example: "my-app@1.2.3"
});Deployment Context
obs.setContext('deployment', {
release: '1.2.3',
commit: 'abc123',
deployedAt: '2024-01-15T10:00:00Z',
deployedBy: 'ci/cd',
});Setting Context Globally vs Per-Error
Global Context
Set once, applies to all errors:
// At app initialization
obs.setUser({ id: user.id, email: user.email });
obs.setTags({ environment: 'production', version: '1.2.3' });
obs.setExtra({ featureFlags: flags });
obs.setContext('subscription', subscription);Per-Error Context
Override global context for specific errors:
obs.captureException(error, {
// Overrides global user
user: { id: 'different-user' },
// Merges with global tags
tags: { specific: 'tag' },
// Overrides global extra
extra: { specificData: 'value' },
// Adds to global contexts
contexts: {
specific: { data: 'value' },
},
});Clearing Context
Clear All
obs.clearContext();Clear Specific
obs.setUser(null);
obs.setTags({});
obs.setExtra({});
obs.setContext('subscription', null);Viewing Context in Dashboard
Issue List
Filter issues by tags:
- Environment: production/staging
- Version: 1.2.3
- Feature: checkout
Issue Detail
View full context:
- User tab - User info and affected count
- Tags tab - All tags
- Context tab - Extra data and custom contexts
- Request tab - HTTP request details
- Device tab - Browser, OS, device info
Best Practices
1. Set User Context Early
// After authentication
onAuthSuccess((user) => {
obs.setUser({
id: user.id,
email: user.email,
});
});2. Use Tags for Filtering
// Tags you'll filter by in dashboard
obs.setTags({
environment: process.env.NODE_ENV,
version: process.env.APP_VERSION,
team: 'payments',
});3. Add Context at Key Points
// When user enters a flow
function startCheckout(cart: Cart) {
obs.setContext('cart', {
itemCount: cart.items.length,
total: cart.total,
});
}4. Don't Include Sensitive Data
// Bad
obs.setExtra({ creditCard: card.number });
// Good
obs.setExtra({ cardLast4: card.number.slice(-4) });5. Keep Context Relevant
// Good - relevant to debugging
obs.captureException(error, {
extra: {
userId: user.id,
action: 'purchase',
},
});
// Bad - irrelevant noise
obs.captureException(error, {
extra: {
randomNumber: Math.random(),
currentTime: Date.now(),
},
});Next Steps
- Alerts - Configure error notifications
- Breadcrumbs - Track user actions
- Capturing Errors - Learn capture methods
On This Page
- Overview
- User Context
- Setting User Context
- Clearing User Context
- User Context on Capture
- User Count Tracking
- Tags
- Setting Global Tags
- Setting Tags on Capture
- Common Tags
- Tag Limits
- Extra Data
- Setting Global Extra
- Setting Extra on Capture
- Extra Data Best Practices
- Extra Limits
- Request Context
- Automatic Request Context
- Manual Request Context
- Request Context Structure
- Sensitive Data Scrubbing
- Device/OS Context
- Automatic Device Context
- Manual Device Context
- Custom Contexts
- Setting Custom Contexts
- Context on Capture
- Environment and Release
- Environment
- Release
- Deployment Context
- Setting Context Globally vs Per-Error
- Global Context
- Per-Error Context
- Clearing Context
- Clear All
- Clear Specific
- Viewing Context in Dashboard
- Issue List
- Issue Detail
- Best Practices
- 1. Set User Context Early
- 2. Use Tags for Filtering
- 3. Add Context at Key Points
- 4. Don't Include Sensitive Data
- 5. Keep Context Relevant
- Next Steps