1. Courses
  2. Developer Foundations
  3. JavaScript Deep Dive
  4. Stop 8

40 minIntermediate

Errors, debugging and testing

Bugs are normal. What separates a calm team from a stressed one is how fast they find the cause, and whether they add a check so the same bug cannot come back. This lesson gives you all three skills: reading errors, debugging in VS Code, and writing tests with Vitest.

By the end you can

  • Read a stack trace from the top frame down to the line in your own code
  • Throw useful errors, including custom error classes with a cause
  • Debug Node and NestJS in VS Code with breakpoints, conditional breakpoints, logpoints and a launch.json
  • Write Vitest unit tests with assertions and mocks, and read a coverage report
  • Explain the testing pyramid and what each layer costs

The everyday picture

At month end, the stock count at a store shows 12 fewer bottles of cooking oil than the system says. A good manager does not guess. First, find the discrepancy: which article, which day, how many. Second, find the cause: walk back through the goods received notes, the sales and the transfers until one entry does not match. Third, and this is the step people skip, add a check so it cannot happen again: maybe the receiving staff now scan every carton instead of counting by eye.

Debugging code is the same audit. The error message and stack trace tell you where the numbers stopped matching. The debugger lets you walk back through the records one step at a time. And a test is the new check at the receiving door: once it exists, that exact bug gets caught every time, by a machine, before a customer sees it.

Errors and stack traces

When JavaScript hits a problem it cannot handle, it an error object. Built-in ones include TypeError (you used a value the wrong way, such as reading a property of undefined), RangeError and SyntaxError. Every Error has a name, a message and a stack. The is the most useful one: the chain of function calls that were running when the error was created, newest first.

Here is a real one. A cashier types a discount code that does not exist, FEST25:

Output
file:///home/you/checkout-lab/src/discount.js:14
  if (subtotal < rule.minSubtotalCents) return 0;
                      ^

TypeError: Cannot read properties of undefined (reading 'minSubtotalCents')
    at calculateDiscount (file:///home/you/checkout-lab/src/discount.js:14:23)
    at buildReceipt (file:///home/you/checkout-lab/src/receipt.js:6:27)
    at file:///home/you/checkout-lab/scripts/typo.js:6:23
    at ModuleJob.run (node:internal/modules/esm/module_job:343:25)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:665:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5)

Node.js v22.22.0

Read it in this order. The message first: something was undefined when the code tried to read minSubtotalCents from it. Then the first frame: discount.js, line 14, column 23, inside calculateDiscount. Node even prints that line with a caret under the exact spot. Then walk down: buildReceipt called it from receipt.js line 6, and that was called from typo.js. The frames starting with node:internal are Node's own machinery; you can skip them. In a big NestJS app, the first frame is often inside node_modules. Keep walking down until you reach the first file your team wrote. That is usually where the fix goes.

Quick check

An error says Cannot read properties of undefined (reading 'capCents') on the line Math.min(discount, rule.capCents). What was undefined?

TypeError Cannot read properties of undefined 1. what went wrong at calculateDiscount discount.js:14:23 2. where thrown here at buildReceipt receipt.js:6:27 3. who called it at file://... typo.js:6:23 your script, top level at ModuleJob.run (node:internal/...) Node's own code: skip calls calls calls
A stack trace is newest first. Read the message, then the top frame (where the error was thrown), then walk down through the callers. Skip node:internal frames and library frames until you reach your own code.

Loading the rest of the lesson…