Reading the Trace of Your Own Error

Joan’s port now handles a missing export politely, and anything it doesn’t expect still crashes with a stack trace. You’ve read crash reports before: the first at line is where it happened.

The finished port checks the rows in a function, checkRows(), whose catch will take each RangeError from parseAmount() and reject the row, so those won’t crash the script. To see where one comes from, Joan runs a copy of checkRows() without that catch. In this lesson, you’ll find the frame that says which code handed parseAmount() the bad text, and keep the trace when you catch an error.

Read the Trace From the Top

Here’s that copy, run in the donations/ folder on the first three lines of October’s export. It keeps parseAmount() and the real destructuring, but its checkRows() only adds up the amounts, with no catch and no rejected list:

Language: JavaScript Filename: traces.js
function parseAmount(text) {
  const amount = Number(text);
  if (text.trim() === "" || !Number.isFinite(amount)) {
    throw new RangeError(`amount is not a number, got "${text}"`);
  }
  if (amount <= 0) {
    throw new RangeError(`amount must be positive, got ${amount}`);
  }
  return amount;
}

function checkRows(lines) {
  let total = 0;
  for (const line of lines.slice(1)) {
    const [date, donor, amountText] = line.split(";");
    total += parseAmount(amountText);
  }
  return total;
}

const lines = [
  "date;donor;amount",
  "2026-10-03;D-101;50.00",
  "2026-10-07;D-102;n/a",
];
console.log(checkRows(lines));

The 50.00 row goes through, and D-102’s "n/a", the export’s third line, stops the script:

Language: Shell
$ node traces.js
file:///home/joan/donations/traces.js:4
    throw new RangeError(`amount is not a number, got "${text}"`);
          ^

RangeError: amount is not a number, got "n/a"
    at parseAmount (file:///home/joan/donations/traces.js:4:11)
    at checkRows (file:///home/joan/donations/traces.js:16:14)
    at file:///home/joan/donations/traces.js:26:13
    at ModuleJob.run (node:internal/modules/esm/module_job:569:25)
    at async node:internal/modules/esm/loader:650:26
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:105:5)

Node.js v26.13.0

Locked learning resources

Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Already a member? Sign-In

Locked learning resources

The full lesson is for members only. Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Already a member? Sign-In

Become a Member to join the conversation.