easyEngineering Practices#77

Console.log debugging pattern

Prompt

Add strategic console.log statements to a nested function to trace the flow of data. Use labeled logging so each log shows which function produced it.

Solution

function outer(x) {
  console.log('[outer] input:', x)
  function middle(y) {
    console.log('[middle] input:', y)
    function inner(z) {
      console.log('[inner] input:', z, 'output:', z * 2)
      return z * 2
    }
    const result = inner(y + 1)
    console.log('[middle] output:', result)
    return result
  }
  const result = middle(x * 2)
  console.log('[outer] output:', result)
  return result
}
Mentor's take

Print debugging is legitimate — every senior uses it — but the difference between noise and signal is structure. The pattern here is deliberate: a [functionName] label on every line so interleaved output stays attributable, and logging both input and output at each layer so one read of the console shows exactly where the data diverged from your mental model. Unlabeled console.log(x) scattered around forces you to correlate values to call sites from memory, which is where the technique gets its bad reputation.

Two upgrades to name in an interview. First, in React Native the structured console feeds straight into React Native DevTools (the modern debugger that replaced Flipper for JS debugging), where a breakpoint often beats twenty logs — logs shine when the bug is timing- or flow-shaped and stepping would perturb it. Second, logs have a lifecycle: trace logs like these are scaffolding and come out before merge, while what ships is structured logging with levels, stripped or gated in release builds — console.log in a hot path costs real performance in production, and logged payloads are a classic PII leak (babel-plugin-transform-remove-console is the standard strip).

Red flag: "I'd add console.logs" as your production debugging answer — production is crash reporting and breadcrumbs; ad-hoc logs are a local tool.

Say it: "I label every trace log with its source and log inputs and outputs in pairs — and none of it ships: release builds get leveled, stripped, PII-safe logging."