JavaScript Tutorial menu

JavaScript Debugging With DevTools

Debugging means finding and fixing mistakes (bugs) in your code. Every browser has free tools for this, called DevTools.

Opening DevTools

BrowserShortcut
Chrome, EdgeF12 or Ctrl + Shift + I (Cmd + Option + I on Mac)
FirefoxF12 or Ctrl + Shift + I
Any browserRight-click on the page and choose Inspect

The tabs you will use most:

TabUse it to
ConsoleSee errors and messages, and run JavaScript
Elements (Inspector)See and edit the live HTML and CSS
Sources (Debugger)Pause code with breakpoints and step through it
NetworkSee every file and request the page loads
Application (Storage)See localStorage, sessionStorage and cookies

Reading an Error Message

When code breaks, the Console shows a red message like this:

Output
Uncaught TypeError: Cannot read properties of undefined (reading 'price')
    at getTotal (shop.js:14:22)
    at HTMLButtonElement.<anonymous> (shop.js:30:5)

Read it in three parts:

  1. The type: TypeError, a value was not what the code expected
  2. The message: something was undefined when you tried to read price from it
  3. The location: file shop.js, line 14, column 22, inside getTotal. Click it to jump to that line

The lines below are the stack trace: the chain of calls that led to the error.

More Than console.log

The console object has many useful methods:

Example

html
<!DOCTYPE html>
<html>
<body>

<p>Open DevTools (F12), go to the Console tab, then press Run again.</p>
<p id="demo"></p>

<script>
const students = [
  { name: "Ali", marks: 78 },
  { name: "Sana", marks: 92 },
  { name: "Hamza", marks: 45 }
];

console.log("Plain message");
console.info("Info: loaded", students.length, "students");
console.warn("Warning: Hamza is close to failing");
console.error("Error: example error message");
console.table(students);

console.group("Results");
students.forEach(s => console.log(s.name, s.marks >= 50 ? "pass" : "fail"));
console.groupEnd();

console.time("loop");
let sum = 0;
for (let i = 0; i < 1_000_000; i++) sum += i;
console.timeEnd("loop");

console.assert(sum > 0, "Sum should be positive");
document.getElementById("demo").textContent = "Done! Check the Console.";
</script>

</body>
</html>
Try it Yourself »
MethodShows
console.log()A normal message
console.warn() / console.error()Yellow warning / red error
console.table(array)An array of objects as a table
console.group() / groupEnd()Folds messages into a group
console.time(label) / timeEnd(label)How long code took
console.assert(condition, msg)Shows msg only if the condition is false
console.count(label)How many times this line ran

Tip: write console.log({ total, discount }) with curly brackets. The Console then shows the variable names next to their values.

Breakpoints

console.log is fine for small things, but a breakpoint is more powerful. It pauses the code on a line, so you can look at every variable at that moment.

  1. Open the Sources tab and find your file
  2. Click the line number. A blue marker appears
  3. Do the action that runs that code (for example, click the button)
  4. The page freezes on that line. Hover over variables to see their values, or look in the Scope panel

The debugger Statement

You can also put a breakpoint in the code itself with debugger;. When DevTools is open, the code pauses there. When DevTools is closed, it does nothing.

Example

html
<!DOCTYPE html>
<html>
<body>

<p>Open DevTools first, then click the button.</p>
<button id="btn">Calculate bill</button>
<p id="demo"></p>

<script>
function calculateBill(items) {
  let total = 0;
  for (const item of items) {
    debugger;   // pauses here on every loop round
    total += item.price * item.qty;
  }
  return total;
}

document.getElementById("btn").addEventListener("click", () => {
  const items = [
    { name: "Naan", price: 30, qty: 4 },
    { name: "Karahi", price: 1800, qty: 1 }
  ];
  document.getElementById("demo").textContent = "Total: Rs " + calculateBill(items);
});
</script>

</body>
</html>
Try it Yourself »
Output
Total: Rs 1920

Remember to remove debugger lines before you publish your site.

Stepping Through Code

While paused, use the buttons at the top of the debugger panel:

ButtonShortcutWhat it does
ResumeF8Run until the next breakpoint
Step overF10Run this line, then pause on the next one
Step intoF11Go inside the function called on this line
Step outShift + F11Finish this function and pause after it

The Watch panel lets you type an expression, like item.price * item.qty, and see its value change as you step.

Other Useful Breakpoints

  • Conditional breakpoint: right-click a line number and add a condition like item.qty > 10. It only pauses when the condition is true.
  • Logpoint: right-click and add a message. It logs without changing your code.
  • Event listener breakpoints: in Sources, pause whenever any click or keydown happens.
  • Pause on exceptions: pause exactly where an error is thrown.

Checking Requests in the Network Tab

If fetch does not work, open Network and run it again. Click the request to see:

  • The status (200 is OK, 404 is not found, 500 is a server error)
  • The Headers you sent and received
  • The Response the server sent back

A Simple Debugging Routine

  1. Read the error message and go to the line it names
  2. Make the bug happen again, the same way, every time
  3. Pause before the line and check the values
  4. Find the first value that is wrong, then ask why
  5. Fix it, and test again with good and bad input

Exercise

Exercise

What does the debugger; statement do when DevTools is open?

Learn JavaScript with a teacher

Join the Web Development course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp