Cloud Parts

Error tracking

Catch every exception with its stack trace and context, and fold thousands of copies into one issue you can fix.

3 technologies on this page ↓
Live model
What you’re watchingTwo services report every exception. The tracker fingerprints each event from its stack trace, so all copies of the same bug (same color) pile up in one issue instead of three thousand alerts.

How it works

An SDK inside the app hooks the language’s handler for uncaught exceptions, and lets you report caught ones too. For each error it sends an event: the exception type and message, the stack trace, and context such as the release, environment, user ID and request URL, plus breadcrumbs, the last few log lines, HTTP calls and clicks before the crash. The server computes a fingerprint for each event, typically from the app’s own stack frames (library frames are ignored), else from the exception type and message, else from the message alone with its parameters stripped. Events with the same fingerprint become one issue with a count, first and last seen times and the number of users hit, so a crash that happens 10,000 times is one line. Alerts go out when a new issue appears, when an issue marked fixed in one release comes back in a later one (a regression), or when a count spikes, not for every event. Minified JavaScript and stripped native binaries produce unreadable traces, so the build uploads source maps or debug symbols and the server turns frames back into original file names and line numbers. Unlike a log store, which keeps every line, an error tracker deduplicates and gives each issue a state (new, resolved, regressed, archived), much like a bug tracker.

Think of it as

A repair shop’s complaints desk. Five hundred customers report the same rattle; the desk files one ticket marked “500 reports, started after the March model”, with the notes from the first few customers attached, and reopens it if the rattle comes back after the fix.

Reach for it when

  • Any app with users you can’t watch: web front ends, mobile apps, APIs, background jobs
  • Finding which release introduced a crash, and how many users it hits
  • Turning minified JavaScript or native crash dumps back into readable stack traces

Think twice when

  • As your only telemetry: it sees exceptions, not slow requests, wrong answers or a service that never got the request
  • Sending expected conditions, such as validation failures, as errors; they bury real issues and cost event quota

A real example

Release 4.2.0 of a web shop goes out at 14:00. Within 20 minutes TypeError: Cannot read properties of undefined (reading 'price') arrives 3,100 times from 870 users, but it is one new issue and one chat alert. The uploaded source map points at cart/total.ts:57, and the breadcrumbs show the cart API returned an empty item list just before. The fix ships in 4.2.1 and the issue is marked resolved in that release; if the same fingerprint shows up again in 4.2.3, it reopens as a regression.

Technologies

Specific products, and what each does differently.

Also used for error tracking

Products of other kinds that are often used this way, grouped by what they are.

What each provider calls it

AWS
No dedicated error tracker; CloudWatch RUM records client-side errors, crashes and app hangs from real user sessions
Google Cloud
Error Reporting, which groups errors found in Cloud Logging
Azure
Application Insights exception telemetry
Open source & others
GlitchTip (MIT, accepts Sentry SDKs); Sentry self-hosted (source-available FSL); hosted: Sentry, BugSnag (SmartBear), Rollbar, Honeybadger, Datadog Error Tracking, Better Stack Errors (accepts Sentry SDKs)

Same idea, different names#

Every tool groups occurrences into something you triage, but the words and the default rules differ. All of them let you override grouping with your own fingerprint.

ToolOne occurrenceThe groupDefault grouping
SentryEventIssueThe app’s own stack frames; else exception type and value; else the message
BugSnagEventErrorError class plus file and line of the top in-project stack frame
RollbarOccurrenceItemIts own grouping engine, with custom fingerprint rules
Google Cloud Error ReportingError eventError groupException type and the five topmost frames; else the message’s first three tokens
Datadog Error TrackingErrorIssueSimilar errors grouped into one issue
  • Grouping by message alone is fragile: messages often contain IDs, amounts or timestamps, so one bug splits into thousands of groups. Sentry’s docs call exception-based grouping “a lot less reliable because of changing error messages”.

In code · python

import sentry_sdk

sentry_sdk.init(dsn=SENTRY_DSN, release="shop@4.2.0", environment="production")
sentry_sdk.set_user({"id": "42"})
sentry_sdk.add_breadcrumb(category="cart", message="cart API returned 0 items", level="info")

def charge(order):
    try:
        return payments.charge(order)
    except PaymentTimeout as err:
        with sentry_sdk.new_scope() as scope:
            scope.fingerprint = ["payments", "timeout"]   # every timeout: one issue
            sentry_sdk.capture_exception(err)
        raise

# uncaught exceptions are captured automatically

Often confused with

Where it came from1999–2024

Before error trackers, a crash was a line in a log or an email. Microsoft hit the problem first at scale. Windows Error Reporting, in use since 1999 and built into every Windows system since XP, collected crash reports from about a billion computers. Its 2009 paper explains that, collected naively, the reports “would absolutely overwhelm programmers”, so WER sorted them into buckets, aiming for “one bug per bucket and one bucket per bug”, and used the bucket counts to decide what to fix first.

Web frameworks had the same flood on a smaller scale. Rails’ Exception Notifier plugin reported errors by email, and Django sent an email for every error, so a busy site filled inboxes with copies of one crash. In May 2008 David Cramer made the first commit of django-db-log, which stored exceptions in a database and showed them in aggregate; it grew into Sentry. In July 2008 thoughtbot launched Hoptoad, a hosted replacement for Exception Notifier where you could sort errors by project and mark them resolved; a trademark complaint made it Airbrake in 2011.

As front ends moved to minified JavaScript, stack traces pointed at line 1 of a one-line file. Source maps, first created by Joseph Schorr for Google’s Closure Inspector, map compiled code back to the original, and one of the format’s stated goals is server-side stack trace deobfuscation. After years as an informal Google Doc, the format became the Ecma standard ECMA-426 in December 2024.

Why it’s built this way

Group by stack trace, not by message
Messages carry IDs and values that differ on every occurrence. The code path that failed is a far more stable identity for “the same bug”, which is why WER, Sentry, BugSnag and Google all key on stack frames first.
Only the app’s own frames count
Two crashes that differ only inside a framework or library are usually one bug in your code. Sentry groups only by frames the SDK marks as in-app, and BugSnag uses the top in-project frame.
Capture context at the moment of the crash
By the time someone looks, the request is gone. Breadcrumbs, release, user and environment travel with the event, so the issue page answers “what was happening?” without reproducing it.
Resolve against a release
Marking an issue fixed in version 4.2.1 lets the tracker ignore stragglers still running 4.2.0 and flag a real regression when the same fingerprint appears in a newer version.

Timeline

  1. 1999

    Windows Error Reporting goes into use, bucketing crash reports

  2. 2008

    First commit of django-db-log, later Sentry (May)

  3. 2008

    thoughtbot launches Hoptoad, a hosted error catcher for Rails (July)

  4. 2009

    Microsoft publishes ten years of WER experience at SOSP

  5. 2011

    Hoptoad is renamed Airbrake

  6. 2024

    Source maps become the Ecma standard ECMA-426

Sources19

Improve this page on GitHub