Errors and Debugging
Throw, catch, and diagnose failures with structured errors and built-in debug tools. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Search across all documentation pages
Throw, catch, and diagnose failures with structured errors and built-in debug tools. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Attach an underlying error with { cause } to preserve context.
const root = new Error("db down");
const err = new Error("query failed", { cause: root });
(err.cause as Error).message // "db down"
err.message // "query failed"Subclass Error for typed handling and stable name / code fields.
class AppError extends Error {
constructor(readonly code: string, message: string) {
super(message);
this.name = "AppError";
}
}
const e = new AppError("E_AUTH", "nope");
e.code // "E_AUTH"
e.name // "AppError"Fail fast in scripts and tests with node:assert/strict.
import assert from "node:assert/strict";
assert.equal(1 + 1, 2);
assert.ok(true);
// assert.equal(1, 2) throws AssertionErrorEnable core debug categories with the NODE_DEBUG environment variable.
// NODE_DEBUG=http,net node app.js
process.env.NODE_DEBUG ?? "" // "" unless setIncrease stack trace depth when diagnosing deep call chains.
Error.stackTraceLimit = 50;
Error.stackTraceLimit // 50Pretty-print objects with controlled depth and colors.
import { inspect } from "node:util";
const s = inspect({ a: { b: 1 } }, { depth: 2, colors: false });
s.includes("b: 1") // trueCreate a debug logger gated by NODE_DEBUG namespaces.
import { debuglog } from "node:util";
const debug = debuglog("myapp");
typeof debug // "function"
// prints only when NODE_DEBUG=myappWrap multiple failures from Promise.any or batch jobs.
const err = new AggregateError(
[new Error("a"), new Error("b")],
"all failed",
);
err.errors.length // 2
err.message // "all failed"Always close resources in finally even when throwing.
const steps: string[] = [];
try {
steps.push("body");
} finally {
steps.push("finally");
}
steps
// ["body", "finally"]Narrow unknown catch values before reading message/stack.
function messageOf(e: unknown) {
return e instanceof Error ? e.message : String(e);
}
messageOf(new Error("x")) // "x"
messageOf("y") // "y"Retry operational errors (timeouts); crash or alert on programmer bugs (TypeError).
const e = Object.assign(new Error("timeout"), { code: "ETIMEDOUT" });
(e as any).code === "ETIMEDOUT" // true
// if operational -> retry; if TypeError -> throwCentralize unhandled rejection logging in long-running servers.
// process.on("unhandledRejection", (r) => console.error("unhandled", r));
typeof process.on // "function"Prefer inspector for stacks; signal-based debugging is platform-specific.
// node --inspect=9229 app.js then chrome://inspect
process.execArgv // may include inspect flags when setAssert that an async function rejects in tests.
import assert from "node:assert/strict";
await assert.rejects(async () => {
throw new Error("fail");
}, /fail/);
// passes when rejection matchesAbortError names appear from AbortSignal - detect and ignore cancellation.
const ac = new AbortController();
ac.abort();
const e = new DOMException("Aborted", "AbortError");
e.name // "AbortError"
// if ((e as Error).name === "AbortError") return;Stack versions: Node.js 24.18.0 (LTS line 24) · TypeScript 5.6+ · npm 10+
Reviewed by Chris St. John·Last updated Jul 18, 2026