awesome-everything RU
↑ Back to the climb

Base CS from zero

When a program fails: code and trace reading

Crux Read a stack trace and short snippets, then classify each failure: which line threw, whether it is a defined error or undefined behaviour, and where the real cause lives.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at middle altitude — in the sky
◷ 14 min

A failure is read in two places: the code that ran and the trace the runtime printed. For each snippet below, do what a working engineer does first — locate the throw site, name the kind of failure, and decide where the real cause lives.

Goal

Practise the reading loop the unit built toward: parse a stack trace top-down to find the throw site, classify a failure as a defined error or undefined behaviour, and separate where an exception surfaced from where its cause actually sits.

Snippet 1 — read the trace

Error: Cannot read properties of undefined (reading 'name')
    at formatLabel (render.ts:14)
    at renderRow (render.ts:31)
    at renderTable (render.ts:48)
    at main (app.ts:9)
Quiz

Reading this trace top-down, which statement is correct?

Snippet 2 — classify the failure

function loadUser(record) {
  return record.profile.name.toUpperCase();
}
loadUser({ profile: null });  // profile is null, not an object
Quiz

record.profile is null, so the code reads .name from null. What kind of failure is this in JavaScript, and how will you find out about it?

Snippet 3 — out of bounds, two languages

prices = [10, 20, 30]   // valid indices 0, 1, 2
read prices[5]          // index 5 — two past the end
Quiz

The same out-of-range read runs in a bounds-checked language and in a low-level unchecked language. How do the two outcomes differ?

Snippet 4 — throw site is not the cause

function parseAge(text) {
  const n = Number(text);
  if (Number.isNaN(n)) throw new Error("not a number: " + text);
  return n;
}

function loadProfile(raw) {
  return { age: parseAge(raw.age) };   // raw.age came from upstream
}
// raw.age is "thirty" — never validated before reaching here
Quiz

The trace tops out at parseAge ('not a number: thirty'). A debugging hypothesis must separate where the error surfaced from where the cause lives. Which reading is right?

Recap

Every failure is read in code and trace: a trace is parsed top-down, the top line is the throw site and the bottom is just the entry; a property read on null is a defined error that raises loudly, while an unchecked out-of-bounds read is undefined behaviour that returns garbage silently; and the throw site is where the error surfaced, not always where the cause lives. Classify the failure, locate where it surfaced, then reason down the chain to the step that first went wrong.

Continue the climb ↑When a program fails: hunt two bugs by reasoning
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.