Skip to content

Cloud & Infrastructure · Observability

Error Tracking in 2026: What Sentry Catches That Your Logs Don't

Logs tell you what happened. Error tracking tells you what broke, in what context, for which users. Here's how to set up Sentry properly and avoid the alert fatigue that makes it useless.

Anurag Verma

Anurag Verma

6 min read

Error Tracking in 2026: What Sentry Catches That Your Logs Don't

Sponsored

Share

Your logs tell you that something happened. An error tracking system tells you what broke, where in the code, who it affected, how many times, and what the user was doing when it happened. They’re not the same thing, and running one without the other leaves gaps.

Sentry is the most widely deployed error tracking platform for web applications. This is a practical setup guide — what to instrument, what to skip, and how to avoid the noise that makes most teams stop looking at their error dashboard within a month.

The Setup

For a Next.js app:

npm install @sentry/nextjs
npx @sentry/wizard@latest -i nextjs

The wizard creates sentry.client.config.ts, sentry.server.config.ts, and sentry.edge.config.ts. It also wraps your next.config.js. For new projects, run the wizard. For existing projects, be careful about the config merge — check what it writes before committing.

Minimal client config:

// sentry.client.config.ts
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  environment: process.env.NODE_ENV,
  tracesSampleRate: 0.1,       // 10% of transactions for performance monitoring
  replaysSessionSampleRate: 0.05,    // 5% of sessions recorded
  replaysOnErrorSampleRate: 1.0,     // 100% of sessions that contain an error
  integrations: [
    Sentry.replayIntegration({
      maskAllText: true,    // mask PII in session replays
      blockAllMedia: false,
    }),
  ],
});

The tracesSampleRate deserves attention. At high traffic, 100% tracing generates significant data volume and cost. 10% is a reasonable default for most apps. If you care more about detecting latency regressions than individual traces, 5% is fine. If you’re debugging a specific slow path, bump it to 100% temporarily and bring it back down.

Source Maps

Without source maps, your stack traces show minified production code. Line 1, column 47832 doesn’t help anyone debug.

Sentry uploads source maps during the build via the Next.js plugin:

// next.config.ts
import { withSentryConfig } from "@sentry/nextjs";

export default withSentryConfig(nextConfig, {
  org: "your-org",
  project: "your-project",
  silent: true,
  widenClientFileUpload: true,
  hideSourceMaps: true,    // don't serve maps to the browser
  disableLogger: true,
});

Set SENTRY_AUTH_TOKEN in your CI environment. Maps upload automatically during next build. They’re stored on Sentry’s servers for symbolicating stack traces, not exposed in your deployed bundle.

Capturing the Right Errors

Sentry automatically captures unhandled exceptions and unhandled promise rejections. What it doesn’t do automatically: capture handled errors you decide to track, add user context, or distinguish between “expected and recoverable” and “something is wrong.”

For explicit error capture with context:

import * as Sentry from "@sentry/nextjs";

async function createPayment(userId: string, amount: number) {
  try {
    const result = await stripe.charges.create({ amount, currency: "usd" });
    return result;
  } catch (error) {
    Sentry.captureException(error, {
      extra: {
        userId,
        amount,
        stripeVersion: stripe.VERSION,
      },
      tags: {
        feature: "payments",
        severity: "high",
      },
    });
    throw error; // re-throw so the caller handles it
  }
}

Adding user context globally so every error includes who it affected:

// In your auth middleware or session setup
Sentry.setUser({
  id: session.userId,
  email: session.email,
});

For React error boundaries:

import * as Sentry from "@sentry/nextjs";

export function ComponentWithBoundary({ children }: { children: React.ReactNode }) {
  return (
    <Sentry.ErrorBoundary
      fallback={<div>Something went wrong. We've been notified.</div>}
      beforeCapture={(scope) => {
        scope.setTag("component", "ComponentWithBoundary");
      }}
    >
      {children}
    </Sentry.ErrorBoundary>
  );
}

Avoiding Alert Fatigue

The reason most teams stop checking their error dashboards: they alert on every error and get buried in noise from expected, unactionable events — bot traffic, crawlers hitting 404s, users typing invalid URLs, browser extensions throwing errors on your pages.

Filter them out at the source:

Sentry.init({
  // ...
  beforeSend(event, hint) {
    const error = hint.originalException;

    if (error instanceof Error) {
      // Known browser noise — not your bugs
      if (error.message.includes("ResizeObserver loop limit exceeded")) return null;
      if (error.message.includes("Non-Error promise rejection")) return null;
      if (error.message.includes("Loading chunk")) return null;
    }

    // Skip crawler traffic
    const ua = event.request?.headers?.["user-agent"] ?? "";
    if (ua.includes("Googlebot") || ua.includes("bingbot")) return null;

    return event;
  },
});

At the alert level, create separate rules for different error rates. A 5% error rate on your payment flow deserves an immediate page. A 0.1% rate on your search page can wait for the morning standup.

Use Sentry’s issue grouping rules to collapse variants of the same underlying error into one issue. Without this, a spike in one error type produces dozens of separate issues with slightly different messages, all pointing to the same root cause.

Performance Monitoring

Sentry’s performance tab shows slowest transactions, P75 and P99 latency, and throughput. For Next.js, it automatically instruments page loads, API routes, and database queries for supported ORMs.

For manual spans around code you care about:

async function fetchUserData(userId: string) {
  return Sentry.startSpan(
    { name: "fetchUserData", op: "db.query" },
    async () => {
      return db.query.users.findFirst({
        where: eq(users.id, userId),
      });
    }
  );
}

The span shows up in transaction traces, making it straightforward to see if a specific function is responsible for latency spikes — and exactly how often it’s called per request.

What Sentry Won’t Do

Error tracking is not a replacement for structured logging. Sentry captures exceptions and their context; it doesn’t capture “this request processed 47 items at 12:03:21.” For event-level logs, you need a log aggregation tool (Axiom, Datadog Logs, Loki, or CloudWatch depending on your stack).

It’s also not an uptime monitor. A server crash produces no Sentry errors if no requests are reaching the server to throw one. Pair Sentry with a basic uptime monitor (Checkly, UptimeRobot, or a simple health check pinger) so you catch the “site is down” case separately from the “site is up but throwing errors” case.

The combination that covers most applications up to mid-scale: Sentry for error tracking and session context, a log aggregator for structured events, and an uptime monitor for availability. You don’t need all three immediately, but you’ll want all three before you’re responsible for a production system that has real users depending on it.

Cost

Sentry’s free tier covers 5,000 errors per month, enough to validate the setup and get comfortable with the interface. After that, the Starter plan at $26/month covers 50,000 errors and 100,000 performance transactions, which works for most early-stage products. The Team plan at $80/month per project adds alerting rules and longer data retention.

If self-hosting is preferred, GlitchTip is an open source Sentry-compatible alternative. It accepts the same SDKs and supports most Sentry features. It requires operational overhead (you’re running the service), but eliminates usage-based billing and keeps error data in your own infrastructure.

Sponsored

Sponsored

Discussion

Join the conversation.

Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.

Sponsored