You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reading an Exception Stack Trace for the Root Cause
When this applies
You have an exception, crash, or stack trace to interpret — from a log, a test
failure, an error tracker, or a terminal — and you need to decide where the
fault actually is.
Do this
Read the deepest Caused by: / cause in the chain first. Frameworks wrap
low-level exceptions in layers of generic ones; the top of the printout is the
last wrapper, the bottom-most cause is the original failure. Diagnose from the
root cause's type, message, and frames.
Within the root cause's frames, find the first frame in your code (your
package/module path), scanning top-down past framework and library frames.
That frame is where your code met the failure; frames above it are machinery.
Read the exception message before the frames — it carries the failing value
(which key was missing, which column, what was null/expected). Frames tell you
where; the message tells you what.
Match the trace to the exact source version that produced it: resolve the
build/commit from the log or artifact and read that revision's line numbers.
Line numbers against a different revision point at the wrong statements.
For async code (async/await, promises, executors, message handlers), the
trace starts at the scheduler, not at your call site. Get the origin:
Case
Do
Node.js / V8 with async/await
await-based code gets async frames in Error#stack (zero-cost async stack traces); prefer async/await over raw promise chains to keep origins visible
Browser JS
Debug with DevTools async stack traces enabled; for production errors, symbolicate first (source maps, row below)
JVM thread pools / executors
The worker thread's trace bottoms out in the pool. Find the scheduling site: search for what submitted the task (wrap submission to capture a creation-site trace when this recurs)
Rethrown exception with the cause dropped (throw new X(...) without the original)
The origin is gone from the trace. Reproduce with a breakpoint/log at the rethrow site to capture the original exception; fix the rethrow to chain the cause
Edge cases
Case
Then
Trace is generic (RuntimeException: error) with your handler on top
Someone caught the real exception and rethrew generically. Go to the catch site in the trace and log/inspect what it swallowed
NPE (or TypeError: cannot read property of undefined) points at a chained call a.b().c().d()
The line does not tell you which link was null. Split the chain into one call per line (or add per-link assertions) and re-run the reproduction