Course:Internet & Tools/
Lesson

Copilot just generated 200 lines of data processing logic. It works, or at least it seems to. But you have no idea what is happening inside. Which functions call which? What does the data look like at each step? Is that intermediate transformation correct? You could read every line carefully, or you could instrument the code with strategic console calls and watch the data flow in real time.

Console mastery is not about console.log('here'). It is about choosing the right console method to answer the specific question you have about unfamiliar code.

Beyond console.log, picking the right method

The four basic methods all write to the console but with different visual treatments. Browsers render warnings in yellow and errors in red, and errors include a stack traceWhat is stack trace?A list of function calls recorded at the moment an error occurs, showing exactly which functions were active and in what order. by default.

// Copilot generated this data pipeline - add logging to understand it
console.log('Processing started', { itemCount: items.length });
console.warn('Skipping 3 items with missing prices');
console.error('Critical: duplicate IDs found in dataset');
console.info('Cache hit - using stored results');
MethodVisual styleStack trace?Use when
logDefaultNoGeneral output, inspecting values
infoBlue icon (some browsers)NoStatus messages, progress updates
warnYellowOptionalDeprecations, risky state, edge cases
errorRedYesActual errors, unexpected states

You can filter the console by severity using the dropdown next to the search box. When AI code generates a wall of logs, filter to "Errors only" to find what actually matters.

02

console.table, the best way to inspect APIWhat is api?A set of rules that lets one program talk to another, usually over the internet, by sending requests and getting responses. data

When you console.log() an object, you get a collapsed tree you have to click through. console.table() renders an array of objects as an actual table with sortable columns, much faster to scan.

// ChatGPT generated this fetch call - what does the data look like?
const response = await fetch('/api/users');
const users = await response.json();

// Instead of this:
console.log(users); // Collapsed object you have to click through

// Do this:
console.table(users);
// Renders a table with columns for every property

console.table(users, ['name', 'role', 'lastLogin']);
// Only shows the columns you care about

This is particularly powerful when debugging AI-generated data transformations. You can log the data before and after each transformation step to verify the AI's logic:

// Claude generated this pipeline - let's verify each step
const raw = await fetchData();
console.table(raw, ['id', 'status', 'amount']);

const filtered = raw.filter(item => item.status === 'active');
console.table(filtered, ['id', 'status', 'amount']);

const totals = filtered.reduce((acc, item) => {
  acc[item.category] = (acc[item.category] || 0) + item.amount;
  return acc;
}, {});
console.table(Object.entries(totals));
When Copilot generates a .filter() or .map() chain, always console.table() the result of each step. AI tools frequently get filter conditions backwards, filtering out the items you wanted to keep. A quick table view catches this in seconds.
03

console.group, organizing logs from complex AI code

When a single user action triggers many function calls in AI-generated code, the output becomes a wall of text. console.group() lets you nest related logs under a collapsible header.

// Instrument AI-generated checkout flow to understand it
function processOrder(order) {
  console.group(`Processing order #${order.id}`);

  console.log('Validating items:', order.items.length);
  console.log('Calculating subtotal...');
  const subtotal = order.items.reduce((s, i) => s + i.price, 0);
  console.log('Subtotal:', subtotal);

  console.group('Applying discounts');
  console.log('Checking coupon code:', order.coupon);
  console.log('Discount applied:', order.discount);
  console.groupEnd();

  console.log('Final total:', subtotal - order.discount);
  console.groupEnd();
}

// Use groupCollapsed for verbose output you rarely need
console.groupCollapsed('API Response Details');
console.log('Status: 200');
console.log('Headers:', response.headers);
console.log('Payload size: 4.2 KB');
console.groupEnd();
04

console.time, measuring AI code performance

console.time() starts a named timer and console.timeEnd() stops it and logs the elapsed time. Use this to check whether AI-generated code is actually fast or just looks fast.

// Is this Copilot-generated sort actually efficient?
console.time('ai-sort');
const sorted = items.sort((a, b) => {
  // Copilot generated this comparator
  return a.name.localeCompare(b.name) || a.date - b.date;
});
console.timeEnd('ai-sort');
// Logs: "ai-sort: 142.35 ms" - that's slow for 1000 items

// Compare with a simpler approach
console.time('simple-sort');
const sorted2 = items.sort((a, b) => a.date - b.date);
console.timeEnd('simple-sort');
// Logs: "simple-sort: 2.18 ms" - the AI over-engineered it
// Time an async operation - works with await too
console.time('api-call');
const response = await fetch('/api/users');
const data = await response.json();
console.timeEnd('api-call');
// Logs: "api-call: 187.12 ms"
console.timeLog() lets you log intermediate checkpoints without stopping the timer. Use it when profiling a multi-step AI pipeline: console.timeLog('pipeline', 'step 2 complete').
05

console.trace, finding who calls what

When you are reading AI-generated code and a function is being called but you are not sure where from, console.trace() prints the full call stackWhat is call stack?The internal mechanism that tracks which function is currently executing and which called it - visible in error stack traces and browser DevTools. without throwing an error.

// ChatGPT generated this utility - who's calling it and when?
function formatCurrency(amount) {
  console.trace('formatCurrency called');
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD'
  }).format(amount);
}
// Output shows every function in the call chain:
// formatCurrency called
//     at formatCurrency (utils.js:2)
//     at renderLineItem (Cart.jsx:45)
//     at Cart (Cart.jsx:12)
06

console.assert, silent sanity checks

console.assert() only outputs anything when the condition is false. This makes it perfect for adding validation to AI code without cluttering the console during normal operation.

// Add sanity checks to AI-generated data transformations
const result = transformData(input);

console.assert(result.length > 0, 'Transform returned empty array', { input });
console.assert(result.every(r => r.id), 'Some results missing ID', { result });
console.assert(result.length === input.length, 'Item count mismatch', {
  input: input.length,
  output: result.length
});
// Logs nothing if all assertions pass - clean console
07

A strategy for instrumenting unfamiliar AI code

When you receive AI-generated code you do not fully understand, follow this pattern:

StepWhat to doConsole method
1Log function entry pointsconsole.group() at the start of each function
2Log input data shapesconsole.table() on parameters
3Log intermediate transformationsconsole.table() after each .map() / .filter()
4Time expensive operationsconsole.time() / console.timeEnd()
5Verify assumptionsconsole.assert() on expected conditions
6Trace unexpected callsconsole.trace() in functions called too often
08

Quick reference

MethodSignatureWhat it does
logconsole.log(...args)General output
warnconsole.warn(...args)Yellow warning
errorconsole.error(...args)Red error with trace
tableconsole.table(data, columns?)Renders as sortable table
groupconsole.group(label)Opens collapsible group
groupCollapsedconsole.groupCollapsed(label)Opens group, collapsed
groupEndconsole.groupEnd()Closes current group
timeconsole.time(label)Starts named timer
timeEndconsole.timeEnd(label)Stops timer, logs ms
timeLogconsole.timeLog(label, ...args)Logs intermediate time
assertconsole.assert(cond, ...args)Logs if condition false
traceconsole.trace(label?)Prints call stack
countconsole.count(label?)Counts how many times called
clearconsole.clear()Clears the console