|$ curl https://forge-ai.dev/api/markdown?path=docs/ops/error-tracking
$cat docs/error-tracking.md
updated Recently·28 min read·published

Error Tracking

OperationsErrorsIntermediate
Introduction

Error tracking captures, groups, and alerts on application errors. Unlike manual log scanning, error tracking platforms automatically group identical errors, track frequency over time, and provide context (stack trace, user session, browser info) for debugging.

Sentry is the industry standard for error tracking, supporting every major framework and language. This guide focuses on Sentry for Next.js/React applications, but the concepts apply to any error tracking tool.

Sentry Setup (Next.js)

Sentry integrates deeply with Next.js to capture server-side errors, client-side errors, and performance data automatically.

sentry-install.sh
Bash
1# Install Sentry for Next.js
2npm install @sentry/nextjs
3
4# Run the Sentry wizard (sets up configuration)
5npx @sentry/wizard -i nextjs
6
7# This creates:
8# - sentry.client.config.ts (browser)
9# - sentry.server.config.ts (server)
10# - sentry.edge.config.ts (edge runtime)
11# - next.config.js modification
sentry.config.ts
TypeScript
1// sentry.client.config.ts — Browser configuration
2import * as Sentry from '@sentry/nextjs';
3import { ExtraErrorData } from '@sentry/integrations';
4
5Sentry.init({
6 dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
7 environment: process.env.NODE_ENV,
8 release: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
9
10 // Performance monitoring (Tracing)
11 tracesSampleRate: 0.25, // Sample 25% of transactions in production
12 replaysSessionSampleRate: 0.1, // Session replay: 10%
13 replaysOnErrorSampleRate: 1.0, // Replay on error: 100%
14
15 // Integrations
16 integrations: [
17 new ExtraErrorData({ depth: 5 }),
18 Sentry.browserTracingIntegration(),
19 Sentry.replayIntegration({
20 maskAllText: true,
21 blockAllMedia: true,
22 }),
23 ],
24
25 // Do not send in development
26 enabled: process.env.NODE_ENV === 'production',
27});
28
29// sentry.server.config.ts — Server configuration
30import * as Sentry from '@sentry/nextjs';
31
32Sentry.init({
33 dsn: process.env.SENTRY_DSN,
34 environment: process.env.NODE_ENV,
35 release: process.env.VERCEL_GIT_COMMIT_SHA,
36 tracesSampleRate: 0.5,
37 enabled: process.env.NODE_ENV === 'production',
38});

info

Set tracesSampleRate between 0.1 and 0.5 for production — 100% sampling generates significant volume and cost. Use 1.0 only in development or low-traffic staging environments. The replaysSessionSampleRate should be even lower (5-10%) to keep session replay storage manageable.
Source Maps Upload

Source maps map minified production JavaScript back to original source code. Without them, stack traces show minified code that is impossible to debug. Sentry automatically uploads source maps during the build process.

next.config.js
JavaScript
1// next.config.js — Sentry source maps
2const { withSentryConfig } = require('@sentry/nextjs');
3
4const nextConfig = {
5 // Your existing Next.js config
6 productionBrowserSourceMaps: false, // Do not expose to users
7};
8
9module.exports = withSentryConfig(nextConfig, {
10 // Sentry webpack plugin options
11 silent: true, // Suppress build logs
12 org: process.env.SENTRY_ORG,
13 project: process.env.SENTRY_PROJECT,
14 authToken: process.env.SENTRY_AUTH_TOKEN,
15
16 // Upload source maps
17 widenClientFileUpload: true,
18 hideSourceMaps: true, // Strip source maps from bundles
19 disableLogger: true,
20});
21
22// Vercel-specific: set SENTRY_AUTH_TOKEN in Vercel env vars
23// Upload happens automatically during build in CI

warning

Never set productionBrowserSourceMaps to true — this exposes your source code to anyone who opens the browser DevTools. Sentry uploads source maps to its own infrastructure (not accessible to end users) for error de-obfuscation.
Error Grouping & Breadcrumbs

Sentry groups identical errors by default using stack trace fingerprinting. You can customize grouping rules and add breadcrumbs — a trail of events leading up to the error — for context.

error-tracking.ts
TypeScript
1// Custom error boundaries and manual error reporting
2import * as Sentry from '@sentry/nextjs';
3import Error from 'next/error';
4
5// Add breadcrumbs manually
6function trackUserAction(action, data) {
7 Sentry.addBreadcrumb({
8 category: 'user-action',
9 message: `User ${action}`,
10 data,
11 level: 'info',
12 });
13}
14
15// Add context (user info attached to all errors)
16Sentry.setUser({
17 id: user.id,
18 email: user.email,
19 username: user.username,
20});
21
22// Set tags for filtering
23Sentry.setTag('subscription_tier', user.plan);
24Sentry.setTag('feature_flag', 'checkout-v2');
25Sentry.setTag('ab_test_group', experiment.group);
26
27// Set extra context
28Sentry.setContext('checkout', {
29 cartItems: cart.length,
30 total: cart.total,
31 coupon: couponCode,
32});
33
34// Manually capture an error
35try {
36 await processPayment(orderId);
37} catch (error) {
38 Sentry.captureException(error, {
39 tags: { orderId: orderId.toString() },
40 contexts: {
41 payment: {
42 provider: 'stripe',
43 amount: order.total,
44 currency: 'USD',
45 },
46 },
47 });
48}
49
50// Capture a message (non-error event)
51Sentry.captureMessage('Database migration completed', {
52 level: 'info',
53 tags: { migration: 'v2', duration: '45s' },
54});
55
56// React Error Boundary
57import { ErrorBoundary } from '@sentry/nextjs';
58
59function MyApp({ Component, pageProps }) {
60 return (
61 <ErrorBoundary
62 fallback={({ error, resetError }) => (
63 <div>
64 <h2>Something went wrong</h2>
65 <button onClick={resetError}>Try again</button>
66 </div>
67 )}
68 onError={(error, info) => {
69 Sentry.captureException(error, { extra: info });
70 }}
71 >
72 <Component {...pageProps} />
73 </ErrorBoundary>
74 );
75}
Release Tracking

Release tracking associates errors with specific application versions. When a new release introduces errors, Sentry shows a regression spike and links to the commit that likely caused it.

sentry-release.sh
Bash
1# Create a release and associate commits (via CI)
2npx sentry-cli releases new "$SENTRY_RELEASE"
3npx sentry-cli releases set-commits "$SENTRY_RELEASE" --auto
4npx sentry-cli releases finalize "$SENTRY_RELEASE"
5
6# In GitHub Actions
7- name: Create Sentry release
8 uses: getsentry/action-release@v1
9 env:
10 SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
11 SENTRY_ORG: my-org
12 SENTRY_PROJECT: my-project
13 with:
14 environment: production
15 version: ${{ github.sha }}
16 sourcemaps: .next/static/chunks
🔥

pro tip

Enable Sentry's "Resolve in Next Release" feature. When a new release is deployed, Sentry automatically marks errors fixed in that release if they have not been seen since. This keeps your error dashboard focused on active issues.
Performance Monitoring with Sentry

Sentry's performance monitoring (tracing) captures request timing, database queries, external API calls, and frontend page loads — all correlated with errors.

sentry-performance.ts
TypeScript
1// Create custom transactions (server-side)
2import * as Sentry from '@sentry/nextjs';
3
4export async function handler(req, res) {
5 const transaction = Sentry.startTransaction({
6 op: 'process-order',
7 name: 'Process Order Handler',
8 tags: { orderId: req.query.id },
9 });
10
11 try {
12 // Automatically captures DB queries and API calls within transaction
13 const order = await db.query('SELECT * FROM orders WHERE id = $1', [req.query.id]);
14 const result = await paymentGateway.charge(order.total);
15
16 res.status(200).json(result);
17 } finally {
18 transaction.finish();
19 }
20}
21
22// Custom spans for manual instrumentation
23async function processRefund(refundId) {
24 const span = Sentry.startInactiveSpan({
25 op: 'refund.provider',
26 name: 'Charge refund via Stripe',
27 attributes: { refundId },
28 });
29
30 try {
31 const result = await stripe.refunds.create({ payment_intent: refundId });
32 span.setStatus({ code: 1 }); // OK
33 return result;
34 } catch (e) {
35 span.setStatus({ code: 2, message: e.message }); // Error
36 throw e;
37 } finally {
38 span.end();
39 }
40}
Alternatives

While Sentry is the most popular error tracking solution, several alternatives offer unique strengths depending on your stack and requirements.

SolutionStrengthsBest For
SentryDeep framework integration, full-stackUniversal error tracking
Datadog RUMReal user monitoring + APM + logs unifiedAll-in-one observability
LogRocketSession replay, network recordingFrontend UX debugging
TrackJSLightweight, focused on JavaScript errorsSimple frontend-only error tracking
RollbarReal-time, deploy tracking, telemetryTeams needing deploy tracking
$Blueprint — Engineering Documentation·Section ID: OPS-ERROR-01·Revision: 1.0