Error Tracking
Temps includes Sentry-compatible error tracking built-in. Use your existing Sentry SDKs without code changes, and own your error data.
Overview
Track, debug, and resolve errors in production with enterprise-grade error tracking included in Temps.
What's Included
- Sentry protocol compatibility
- Error grouping with fingerprinting
- Stack trace analysis
- Source map support
- Real-time error alerts
- Error context (user, request, environment)
- AI-powered error clustering
- Session correlation
Why It Matters
- No third-party services needed
- Use existing Sentry SDKs
- Complete data ownership
- Unlimited events (no pricing tiers)
- Integrated with analytics
- Correlate errors with sessions
- Lower latency (same infrastructure)
Key Features
- Name
Drop-In Replacement- Description
Works with official Sentry SDKs (JavaScript, Python, Go, PHP, Ruby, etc.)
- Name
Smart Grouping- Description
AI-powered error clustering groups similar errors automatically
- Name
Rich Context- Description
Captures request details, user info, environment, custom metadata
- Name
Stack Traces- Description
Full stack traces with source map support for minified code
- Name
Real-Time Alerts- Description
Email, Slack, and webhook notifications for new errors
- Name
Session Correlation- Description
Link errors to session replays for visual debugging
Sentry Compatibility
Temps implements the complete Sentry protocol, allowing you to use official Sentry SDKs without modification.
Supported Features
- Name
Envelope Ingestion- Description
Full Sentry envelope protocol support (v7+)
- Name
Error Events- Description
Exception tracking with stack traces
- Name
Transaction Events- Description
Performance monitoring integration
- Name
Breadcrumbs- Description
Event trail leading up to errors
- Name
User Context- Description
User identification and metadata
- Name
Tags & Metadata- Description
Custom tagging and context
- Name
Releases- Description
Track errors by release version
Compatibility Matrix
Fully Supported SDKs
- @sentry/browser (JavaScript)
- @sentry/react (React)
- @sentry/nextjs (Next.js)
- @sentry/node (Node.js)
- @sentry/python (Python)
- @sentry/go (Go)
- @sentry/php (PHP)
- @sentry/ruby (Ruby)
- @sentry/java (Java)
- @sentry/dotnet (.NET)
Supported Platforms
- Web browsers
- Node.js servers
- React Native
- Electron
- Mobile apps (iOS, Android)
- Desktop apps
- Serverless functions
- Docker containers
Setup & Integration
Get started with error tracking in minutes using your existing Sentry SDK.
Step 1: Get Your DSN
Each project gets a unique DSN (Data Source Name) for error reporting. The DSN format is:
https://<public_key>@<temps_app>/<project_id>
Example DSN format:
https://742ee692155dd1cb2cecd94838bb425d4b5a1184e5b57c0815e9d808a6f8d70d@your-temps-instance.com/1
Get Your DSN
Visit your project's error tracking setup page to view and copy your unique DSN:
https://<temps_app>/projects/<project_slug>/errors?tab=setup
Example:
https://app.temps.davidviejo.dev/projects/my-app/errors?tab=setup
On this page, you'll find:
- Your project's unique DSN - Copy this to use in your Sentry SDK configuration
- Setup instructions for different platforms
- Environment-specific DSNs (if configured)
- Rate limits and configuration options
Important: Each project has a unique DSN. You must copy your actual DSN from the setup page—the DSN shown in examples above is just a format reference. Your DSN will have a different public key.
DSN Format: The DSN consists of:
- Public Key: A 64-character hexadecimal string (unique per project)
- Temps App URL: Your Temps instance URL
- Project ID: Numeric project identifier
The DSN is automatically generated when you first visit the setup page.
Step 2: Install Sentry SDK
Install the official Sentry SDK for your platform:
npm install @sentry/react
Step 3: Configure SDK
Point the Sentry SDK to your Temps instance:
Configure Sentry SDK
import * as Sentry from '@sentry/react';
Sentry.init({
// Copy your DSN from: https://<temps_app>/projects/<project_slug>/errors?tab=setup
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN || 'YOUR_DSN_HERE',
environment: 'production',
release: 'my-app@1.0.0',
// Performance monitoring
tracesSampleRate: 1.0,
// Session replay integration
integrations: [new Sentry.BrowserTracing()],
beforeSend(event, hint) {
// Filter sensitive data
return event;
}
});
Step 4: Test Error Tracking
Trigger a test error to verify setup:
Test Error Tracking
// Throw test error
Sentry.captureException(new Error('Test error from Temps'));
// Capture message
Sentry.captureMessage('Test message', 'info');
// Add breadcrumb
Sentry.addBreadcrumb({
message: 'User clicked button',
level: 'info',
data: { button: 'signup' }
});
Error Grouping
Temps automatically groups similar errors together using smart fingerprinting and AI-powered clustering.
Grouping Strategies
- Name
Stack Trace Fingerprinting- Description
Groups errors with identical stack traces (default)
- Name
Exception Type- Description
Groups by exception class/type (TypeError, ReferenceError, etc.)
- Name
Error Message- Description
Groups by error message pattern (parameterized)
- Name
AI Clustering- Description
Uses OpenAI embeddings to find semantically similar errors
- Name
Custom Fingerprinting- Description
Define custom grouping rules via fingerprint tags
Custom Fingerprinting
Override default grouping with custom fingerprints:
Custom Fingerprinting
Sentry.captureException(error, {
fingerprint: ['database-error', 'connection-timeout'],
});
// Dynamic fingerprint
Sentry.captureException(error, {
fingerprint: ['api-error', error.response?.status],
});
Merge & Split Groups
Merge Groups
Combine multiple error groups that should be treated as one:
temps error-tracking merge \
--groups error-1,error-2,error-3 \
--target error-1
Split Groups
Separate errors that were incorrectly grouped:
temps error-tracking split \
--group error-1 \
--event-ids evt-123,evt-456
Error Details
Each error event captures comprehensive context for debugging.
Error Anatomy
- Name
Exception Info- Description
Type, message, stack trace with line numbers
- Name
Request Context- Description
URL, method, headers, query params, request body
- Name
User Context- Description
User ID, email, IP address, custom properties
- Name
Environment- Description
Browser/runtime version, OS, device type
- Name
Tags- Description
Custom tags (environment, version, feature flags)
- Name
Breadcrumbs- Description
Event trail leading to error (clicks, API calls, console logs)
- Name
Additional Data- Description
Custom metadata, local variables, state snapshots
Enrich Error Context
Add custom context to errors:
Add Context
Sentry.setUser({
id: 'user-123',
email: 'user@example.com',
username: 'johndoe',
subscription: 'pro'
});
Source Maps: Source map upload and parsing is currently a work in progress (WIP). This feature will allow you to upload source maps to debug minified production code with readable stack traces.
Trace Correlation
Temps stores a W3C Trace Context trace ID alongside errors so the unified Observe page can link an exception to the request, spans, and other events that share the same trace. This is what powers the cross-source jumps in the /projects/<slug>/observe timeline.
Schema
The m20260502_000001_add_observe_correlation migration (shipped in temps 0.1.0-beta.6) adds the correlation columns and lookup indexes. Every column is nullable, so existing rows are unaffected, and the migration is written to be safely re-runnable — each step uses IF NOT EXISTS.
| Table | Column | Type | Purpose |
|---|---|---|---|
proxy_logs | trace_id | text (nullable) | W3C trace ID for the request |
proxy_logs | error_group_id | integer (nullable) | Links a request to the error group it produced |
error_events | trace_id_indexed | text (nullable) | Trace ID promoted from the event payload, indexed for joins |
revenue_events | deployment_id | integer (nullable) | Correlate revenue with a deployment |
revenue_events | environment_id | integer (nullable) | Correlate revenue with an environment |
revenue_events | trace_id | text (nullable) | W3C trace ID for the revenue event |
Supporting indexes added by the same migration:
| Index | Definition |
|---|---|
idx_proxy_logs_project_trace | proxy_logs (project_id, trace_id) |
idx_proxy_logs_error_group | proxy_logs (error_group_id) WHERE error_group_id IS NOT NULL |
idx_error_events_project_trace | error_events (project_id, trace_id_indexed) |
idx_revenue_events_project_occurred | revenue_events (project_id, occurred_at DESC) |
How the trace ID is extracted
For error events, temps-error-tracking ingestion probes the event payload for a trace ID and promotes the first valid value to error_events.trace_id_indexed. It checks, in order: data.sentry.contexts.trace.trace_id, top-level data.contexts.trace.trace_id, and data.trace.trace_id. A value is accepted only if it is exactly 32 ASCII-hex characters and is not the all-zero trace ID the W3C spec reserves as invalid.
The temps-proxy reverse proxy includes a helper, extract_traceparent_trace_id, that reads the inbound traceparent request header (matched case-insensitively against traceparent, Traceparent, and TRACEPARENT), splits on -, and takes the trace-id field. It applies the same validation: the value must be 32 ASCII-hex characters, must not be all zeros, and is lowercased before use. Six unit tests cover the valid case, a missing header, the all-zero value, the wrong length, non-hex characters, and uppercase folding.
To send a trace ID through to Temps, set a standard traceparent header on the request:
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
│ └─ trace-id (32 hex) ────────────┘ └─ span-id ──┘ └ flags
└─ version
Proxy proxy_logs.trace_id population is not yet wired. The extract_traceparent_trace_id helper exists and is validated, but the live proxy logging path writes request rows through a batched multi-row INSERT whose column list does not yet include trace_id, so the extracted value is currently dropped before the proxy_logs write. The schema column and indexes are in place, and error events are already correlated via error_events.trace_id_indexed, but do not rely on the proxy populating proxy_logs.trace_id for live requests yet.
Error Resolution
Manage error lifecycle from discovery to resolution.
Error States
- Name
Unresolved- Description
New or ongoing errors (default state)
- Name
Resolved- Description
Marked as fixed (manually or automatically)
- Name
Ignored- Description
Known errors that should be suppressed
- Name
Regressed- Description
Error recurred after being resolved
Mark as Resolved
Resolve Errors
# Resolve error group
bunx @temps-sdk/cli error update --group-id error-123 --project-id <project-id> --status resolved
# Note: --in-release is not supported; resolution is immediate
bunx @temps-sdk/cli error update --group-id error-123 --project-id <project-id> --status resolved
# Resolve multiple groups (run per group)
bunx @temps-sdk/cli error update --group-id error-123 --project-id <project-id> --status resolved
bunx @temps-sdk/cli error update --group-id error-456 --project-id <project-id> --status resolved
bunx @temps-sdk/cli error update --group-id error-789 --project-id <project-id> --status resolved
Auto-Resolution
Configure automatic resolution rules:
# Auto-resolve errors
auto_resolution:
# Resolve if no new events for X days
no_events_for: 30
# Resolve when new release is deployed
on_release: true
# Resolve when error rate drops below threshold
rate_threshold:
errors_per_hour: 1
duration: 24h
Ignore Errors
Suppress known errors you don't want to track:
Ignore Errors
Sentry.init({
dsn: '...',
ignoreErrors: [
// Ignore specific error messages
'ResizeObserver loop limit exceeded',
'Non-Error promise rejection',
// Ignore error patterns
/^Loading chunk [\d]+ failed$/,
],
// Ignore errors from specific URLs
denyUrls: [
/extensions\//i,
/^chrome:\/\//i,
],
beforeSend(event, hint) {
// Custom ignore logic
if (event.exception) {
const error = hint.originalException;
if (error.message?.includes('Network error')) {
return null; // Don't send to Temps
}
}
return event;
}
});