Debugging

Debugging is the process of finding and fixing errors (bugs) in your code. Every developer encounters bugs, and knowing how to debug efficiently is one of the most valuable skills you can have.

A bug can be a typo, wrong logic, or unexpected behavior. Debugging tools help you pause your code, inspect variables, and understand exactly what is happening at each step.

javascript

function add(a, b) {
  return a - b; // bug: should be a + b
}

console.log(add(3, 4)); // Output: -1 (wrong, expected 7)

In the example above, a simple typo (- instead of +) causes the wrong result. Debugging helps you catch and correct these issues.

Google Chrome Developer Tools (DevTools) is a set of tools built directly into the Chrome browser. You can open it by pressing F12 or right-clicking on a page and selecting Inspect.

The most useful panels for JavaScript debugging are:

  • Console — view log messages, run JavaScript, and see errors.
  • Sources — view your source files, set breakpoints, and step through code.
  • Network — inspect HTTP requests and responses.
  • Elements — inspect and modify the HTML and CSS of the page.

For JavaScript debugging, the Console and Sources panels are your best friends.

A breakpoint is a marker you place on a line of code to pause execution there. When the browser hits that line, it stops so you can inspect variables and the program state.

To add a breakpoint in Chrome DevTools:

  • Open DevTools (F12) and go to the Sources panel.
  • Open your JavaScript file from the file tree on the left.
  • Click the line number where you want to pause. A blue marker appears.
  • Reload the page or trigger the action. The code will pause at your breakpoint.

You can also add a breakpoint directly in your code using the debugger statement:

javascript

function calculateTotal(price, tax) {
  debugger; // execution pauses here when DevTools is open
  let total = price + tax;
  return total;
}

calculateTotal(100, 18);

The debugger statement only pauses code when DevTools is open. It has no effect in production if DevTools is closed.

When an error occurs, the browser Console shows a red error message with the file name and line number. Always read the error message carefully — it usually tells you exactly what went wrong and where.

Steps to fix an error:

  • Open DevTools and go to the Console tab.
  • Read the error message and note the file name and line number.
  • Click on the file link in the error to jump to that line in the Sources panel.
  • Inspect the code and look for mistakes — typos, wrong variable names, missing brackets, etc.
  • Fix the code and reload the page to verify the error is gone.

javascript

// Error example
console.log(myVar); // ReferenceError: myVar is not defined

// Fix: declare the variable before using it
let myVar = "Hello";
console.log(myVar); // Output: Hello

console.log() is the most commonly used debugging tool. It prints any value — a string, number, object, or array — to the browser console so you can inspect it.

javascript

let name = "Alice";
let age = 25;

console.log(name);        // Alice
console.log(age);         // 25
console.log(name, age);   // Alice 25

let user = { name: "Alice", age: 25 };
console.log(user);        // { name: "Alice", age: 25 }

You can pass multiple values to console.log() separated by commas, and all of them will be printed on the same line.

console.warn() prints a warning message to the console, typically shown with a yellow background and a warning icon. Use it to alert yourself (or other developers) about something that is not a hard error but could cause problems.

javascript

let age = -5;

if (age < 0) {
  console.warn("Age should not be negative:", age);
}
// Output (in yellow): Age should not be negative: -5

console.error() prints an error message to the console, shown with a red background and error icon. It also includes a stack trace, making it easier to find where the error originated. Use it to log errors that affect functionality.

javascript

function fetchData(url) {
  if (!url) {
    console.error("Error: URL is required to fetch data.");
    return;
  }
  // proceed with fetch...
}

fetchData(); // Output (in red): Error: URL is required to fetch data.

console.table() displays arrays or objects as a neat table in the console. It is very useful when you want to inspect structured data at a glance instead of scrolling through a nested object.

javascript

const users = [
  { name: "Alice", age: 25 },
  { name: "Bob",   age: 30 },
  { name: "Carol", age: 28 },
];

console.table(users);
// Displays a formatted table with columns: name, age

This is much easier to read than console.log(users) when you have an array of objects.

Fixing a bug is a structured process. Following these steps makes debugging faster and prevents the same bug from coming back.

1. Identifying the Bug

The first step is to notice that something is wrong. This can happen through a visible error on screen, an error in the console, incorrect output, or a failing test. Be clear about what the expected behavior is and what is actually happening.

javascript

// Expected: multiply(3, 4) should return 12
// Actual: it returns 7
function multiply(a, b) {
  return a + b; // bug identified: using + instead of *
}

2. Finding the Bug

Once you know there is a bug, find exactly where in the code it is. Use console.log(), breakpoints, or the DevTools Sources panel to trace the flow of your code and inspect variable values.

javascript

function multiply(a, b) {
  console.log("a:", a, "b:", b); // log inputs to trace the issue
  return a + b;
}

console.log(multiply(3, 4)); // Output: a: 3 b: 4 then 7 (reveals the bug)

3. Fixing the Bug

Once you have found the bug, apply the fix. Make a small, focused change and test that the fix works without breaking anything else.

javascript

function multiply(a, b) {
  return a * b; // fixed: changed + to *
}

console.log(multiply(3, 4)); // Output: 12

4. Not Repeating Bugs

After fixing a bug, think about why it happened and how to avoid it in the future. Write a test for it, add a code comment explaining the correct behavior, or refactor the code to make it clearer. This way, the same bug will not appear again.

JavaScript has several built-in error types. Knowing them helps you quickly understand what went wrong.

Syntax Error

A SyntaxError occurs when your code has a typo or is written incorrectly and cannot be parsed by the JavaScript engine. The code will not run at all.

javascript

// Missing closing parenthesis
console.log("Hello"
// SyntaxError: Unexpected end of input

Reference Error

A ReferenceError happens when you try to use a variable that has not been declared.

javascript

console.log(myVariable);
// ReferenceError: myVariable is not defined

Type Error

A TypeError occurs when you try to perform an operation on a value of the wrong type, such as calling a non-function or accessing a property on null or undefined.

javascript

let num = 42;
num.toUpperCase();
// TypeError: num.toUpperCase is not a function

let obj = null;
console.log(obj.name);
// TypeError: Cannot read properties of null

Internal Error

An InternalError is thrown by the JavaScript engine itself when something goes wrong internally, such as too much recursion causing a stack overflow.

javascript

function recurse() {
  return recurse(); // calls itself forever
}

recurse();
// InternalError: too much recursion (in Firefox)
// RangeError: Maximum call stack size exceeded (in Chrome)

Range Error

A RangeError occurs when a value is not within the allowed range, such as creating an array with a negative length or using a number method with an invalid argument.

javascript

let arr = new Array(-1);
// RangeError: Invalid array length

let num = 3.14159;
console.log(num.toFixed(200));
// RangeError: toFixed() digits argument must be between 0 and 100

URI Error

A URIError is thrown when a global URI function like decodeURIComponent() is used with a malformed URI.

javascript

decodeURIComponent("%");
// URIError: URI malformed
  • Debugging is finding and fixing errors in code.
  • Chrome DevTools provides Console, Sources, Network, and Elements panels to help debug.
  • A breakpoint pauses code execution at a specific line so you can inspect state.
  • The debugger statement adds a breakpoint directly in code.
  • console.log() prints values for inspection.
  • console.warn() prints a yellow warning message.
  • console.error() prints a red error message with a stack trace.
  • console.table() displays arrays and objects as a table.
  • Bug fixing steps: Identify, Find, Fix, Prevent recurrence.
  • SyntaxError — invalid code syntax.
  • ReferenceError — using an undeclared variable.
  • TypeError — wrong type operation.
  • InternalError — engine-level error (e.g., stack overflow).
  • RangeError — value out of allowed range.
  • URIError — malformed URI in URI functions.