Error Tracking

Temps includes Sentry-compatible error tracking built-in — point your existing @sentry/react, @sentry/nextjs, or any other Sentry SDK at your Temps DSN and errors appear in your dashboard with zero code changes. No Sentry account, no monthly bill, no data leaving your infrastructure.


How it works

Temps implements the Sentry envelope ingestion protocol at /api/<project_id>/envelope/, so any Sentry SDK works without modification. Error grouping uses a built-in vector similarity engine — no OpenAI API call is made; embeddings are computed locally using a hash tokenizer into a 384-dimension vector, then stored in pgvector for cosine-similarity lookup. The platform captures the full Sentry feature set — envelope protocol (v7+), stack trace fingerprinting, source map parsing, user and request context, breadcrumbs, session correlation, and W3C trace ID correlation with spans and proxy logs — all running on your own infrastructure with no third-party services, no per-event pricing, and full integration with Temps analytics and session replay.

TempsSentry CloudSelf-hosted Sentry
ProtocolSentry envelope (v7+)Sentry envelope (v7+)Sentry envelope (v7+)
SDK compatibilityAll official Sentry SDKsAll official Sentry SDKsAll official Sentry SDKs
Error groupingStack trace + local vector similarityStack trace + ML clusteringStack trace + ML clustering
Source mapsBuilt-in upload + parsingBuilt-inBuilt-in
Session replayBuilt-in (same platform)Add-on (paid plan)Separate setup required
Analytics integrationBuilt-inSeparate productSeparate product
Uptime monitoringBuilt-inSeparate productSeparate product
PricingFree (self-hosted) / ~$6/mo (Cloud)$0–$80+/mo by event volumeSelf-hosted infra cost
Data locationYour serverSentry cloudYour server

Sentry compatibility

Temps implements the complete Sentry envelope 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 and integration

Get started with error tracking in minutes using your existing Sentry SDK.

Step 1: Get Your DSN

Get your project DSN

  1. 1

    Open your project's error tracking setup page at https://<temps_app>/projects/<project_slug>/errors?tab=setup.

  2. 2

    Copy your project's unique DSN from the setup page (the public key is a 64-character hex string unique to your project).

    Checkpoint: Confirm the DSN matches the format https://<public_key>@<temps_app>/<project_id> before pasting it into your SDK config.

  3. 3

    Paste the DSN into your Sentry SDK init (for example as NEXT_PUBLIC_SENTRY_DSN) and trigger a test error with Sentry.captureException(new Error('Test error from Temps')).

  4. 4

    Reload the Error Tracking page in the dashboard to confirm the test event arrived.

    Checkpoint: The new error group appears in the project's error list, confirming the SDK is sending events.

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

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: '[email protected]',

  // Performance monitoring
  tracesSampleRate: 1.0,

  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 stack trace fingerprinting and local vector similarity 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
    Vector Similarity
    Description

    Uses a built-in hash tokenizer + pgvector cosine similarity to find semantically similar errors — computed locally, no external API required

  • 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],
});

Update Group Status

Merge and split operations are available in the dashboard via the Error Details page Actions menu. Use the CLI to update group status:

# Resolve a group
bunx @temps-sdk/cli errors update --group-id <group-id> --project-id <project-id> --status resolved

# Ignore a group
bunx @temps-sdk/cli errors update --group-id <group-id> --project-id <project-id> --status ignored

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: '[email protected]',
  username: 'johndoe',
  subscription: 'pro'
});

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) 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.

TableColumnTypePurpose
proxy_logstrace_idtext (nullable)W3C trace ID for the request
proxy_logserror_group_idinteger (nullable)Links a request to the error group it produced
error_eventstrace_id_indexedtext (nullable)Trace ID promoted from the event payload, indexed for joins
revenue_eventsdeployment_idinteger (nullable)Correlate revenue with a deployment
revenue_eventsenvironment_idinteger (nullable)Correlate revenue with an environment
revenue_eventstrace_idtext (nullable)W3C trace ID for the revenue event

Supporting indexes added by the same migration:

IndexDefinition
idx_proxy_logs_project_traceproxy_logs (project_id, trace_id)
idx_proxy_logs_error_groupproxy_logs (error_group_id) WHERE error_group_id IS NOT NULL
idx_error_events_project_traceerror_events (project_id, trace_id_indexed)
idx_revenue_events_project_occurredrevenue_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

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

Mark an error group as resolved

  1. 1

    Open the Error Details page for the error group you fixed.

  2. 2

    Open the Actions menu and choose Resolve.

  3. 3

    Pick a resolution option: mark as resolved now, resolve in the next release, resolve in a specific release, or set auto-resolve after X days with no new events. (Release-scoped and auto-resolve options are dashboard-only; the CLI always performs an immediate resolve.)

  4. 4

    Confirm the resolution.

    Checkpoint: The error group's status changes to Resolved; if it recurs later it will reappear as Regressed.

Resolve Errors

# Resolve error group
bunx @temps-sdk/cli errors update --group-id <group-id> --project-id <project-id> --status resolved

# Resolve multiple groups (run per group)
bunx @temps-sdk/cli errors update --group-id error-123 --project-id <project-id> --status resolved
bunx @temps-sdk/cli errors update --group-id error-456 --project-id <project-id> --status resolved

Ignore Errors

Ignore a known error group

  1. 1

    Open the Error Details page for the error group you want to suppress.

  2. 2

    Open the Actions menu and choose Ignore.

  3. 3

    Confirm to suppress the group (configure pattern-based ignore rules in the web UI for recurring noise).

    Checkpoint: The error group's status changes to Ignored and it no longer surfaces in the default unresolved list.

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;
  }
});

Additional Resources

Was this page helpful?