Debug code

Pause with a debugger

Set a breakpoint, inspect values and scope, step through control flow, and change no code until the state is understood.

10 minute lesson

~~~

Print debugging costs one edit-and-rerun cycle per question. A debugger lets you stop execution before the wrong result spreads, then ask as many questions as you want about that frozen moment. Inspect actual runtime state instead of adding many speculative logs.

Neither tool is always right. Logs win in production and across many requests. A debugger wins when you have one reproducible failure and need to see state you did not think to print.

Start Node with the inspector

Start a Node process with the inspector:

node --inspect-brk app.mjs

--inspect-brk pauses on the first line, so you have time to set breakpoints before any code runs. Plain --inspect starts executing immediately. Open chrome://inspect in Chrome and click your process under Remote Target — DevTools attaches to the paused process.

Attach DevTools, pause at the relevant function, then work a fixed loop:

1. set a breakpoint on the line before the suspected failure
2. resume, wait for the pause
3. read local values and the call stack — is the state what you assumed?
4. step over (next line) or step into (enter the call), deliberately

The payoff moment: a variable holds a value you were sure it couldn’t. That is the assumption the whole bug was hiding behind, and staring at source code would never have caught it. You can also drop a debugger statement in the code; any attached inspector pauses there.

Conditional breakpoints

When a function runs 500 times and fails once, a plain breakpoint is torture. Right-click the breakpoint and add a condition like item.price === undefined. Execution pauses only on the failing iteration, replacing the whole log-and-grep cycle.

The safety rule

Do not attach an unauthenticated remote debugger to a public interface. The inspector protocol can evaluate arbitrary code — debuggers can execute code with process authority. Keep the inspector bound to 127.0.0.1, and tunnel over SSH when you must debug a remote machine.

And change no code until the state is understood. The debugger’s value is observing the system exactly as it is; the moment you start editing mid-session, you are experimenting, and that belongs in the change-one-variable workflow.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →