EthicsComputerCourses
Join training +91 90532 10052

Reading Errors & Debugging

Intro to Programming · Lesson 17 of 25 Beginner 9 min read Updated

Every programmer, from a school student to a senior engineer, sees error messages every single day. An error message is not the computer telling you off. It is a clue, often a very precise one, about what went wrong and where. Learning to read these clues calmly is one of the most valuable skills in programming.

In this lesson you will learn the three kinds of errors, read Python and JavaScript error messages step by step, and practise a simple method for finding bugs that do not produce any message at all.

Three kinds of errors

KindWhen it shows upExampleDoes the program run?
Syntax errorBefore running, while the code is checkedA missing bracket or colonNo, not even line 1
Runtime errorWhile running, at the line that failsDividing by zero, an unknown nameYes, until that line
Logic errorNever reportedWrong formula, conditions in the wrong orderYes, but the answer is wrong

Syntax and runtime errors at least tell you something is wrong. Logic errors are the sneaky ones: the program runs happily and prints a wrong answer. You catch them only by testing.

Reading a Python traceback

Here is a shop bill program with a bug. The quantity was typed in quotes, so it is a string:

PythonRun it yourself
prices = [120, 80, 45]
quantity = "2"
total = 0
for price in prices:
    total += price * quantity
print("Total:", total)

Running it as a file named bill.py in a terminal shows a traceback, Python's error report:

Text
Traceback (most recent call last):
  File "bill.py", line 5, in <module>
    total += price * quantity
TypeError: unsupported operand type(s) for +=: 'int' and 'str'

Read a traceback from the bottom up:

  1. The last line is the most important. TypeError is the kind of error, and the message says you tried to add (+=) a string (str) to a whole number (int).
  2. The line above shows the code that failed: total += price * quantity.
  3. The File line says where: line 5 of bill.py. (In a terminal you see the full path to your file. In the browser editor the file is called <exec>.)

Now think. Why is there a string? price * quantity is 120 * "2", and multiplying a string by a number repeats it, giving "22222...". The fix is to store the quantity as a number: quantity = 2. The error appeared on line 5, but the real mistake was on line 2. This is very common: the error shows where the program noticed the problem, not always where you made it.

Error types you will meet often

PythonJavaScriptUsual cause
SyntaxErrorSyntaxErrorA missing bracket, quote, colon or comma
IndentationError(none)Python block lines not lined up
NameErrorReferenceErrorA name used before it was created, or misspelt
TypeErrorTypeErrorWrong type: adding text to a number, calling something that is not a function
ValueError(none; often NaN instead)Right type, bad value, such as int("ten")
IndexError(none; gives undefined)Index past the end of a list
ZeroDivisionError(none; gives Infinity)Dividing by zero

Notice how often JavaScript gives a strange value instead of an error. That makes JavaScript bugs show up later and further away from their cause, so check your values carefully.

Reading a JavaScript error

JavaScript errors appear in the browser console (press F12) or in the Try-it output, usually in red:

JavaScriptRun it yourself
const toppers = ["Meera", "Kabir"];
console.log(toppers[0].toUpperCase());
console.log(toppers[2].toUpperCase());

The first line works and prints MEERA. The second fails. In Chrome and Edge the message is:

Text
Uncaught TypeError: Cannot read properties of undefined (reading 'toUpperCase')

"Uncaught" means no code was set up to handle the error, so the program stopped. Read the rest as: "you tried to use toUpperCase on something that is undefined". There is no toppers[2] (the array has indexes 0 and 1), so it is undefined. Other browsers word the message differently, but the error type and the idea are the same. In the browser console, the message also shows the file and line number, which you can click.

Finding logic errors with print

When there is no error message, make the program tell you what it is doing. Add temporary print() or console.log() lines that show the values at each step. This program should print an average of 80:

PythonRun it yourself
marks = [80, 90, 70]
total = 0
for mark in marks:
    total = mark
    print("DEBUG mark =", mark, "total =", total)
average = total / len(marks)
print("Average:", average)
Output
DEBUG mark = 80 total = 80
DEBUG mark = 90 total = 90
DEBUG mark = 70 total = 70
Average: 23.333333333333332

The debug lines show that total never grows: it just copies each mark. The bug is total = mark, which should be total += mark. Fix it, run again to see Average: 80.0, then delete the debug lines.

A debugging checklist

When something goes wrong, work through these steps instead of changing code at random:

  1. Read the whole error message, especially the last line, and go to the line number it gives.
  2. Check the line just above too; a missing bracket on line 4 is often reported on line 5.
  3. Print the values just before the failing line. Are they the type and size you expected?
  4. Make the problem smaller. Copy the failing part into a new file with fixed test values.
  5. Change one thing at a time, and run after each change.
  6. Explain the code out loud, line by line, to a friend or even a toy. This "rubber duck" trick works surprisingly often, because explaining forces you to notice what the code really says.
  7. Search the exact error message online, without your own variable names.

When you are ready for a stronger tool, a debugger lets you pause a program at a chosen line, called a breakpoint, and look at every variable. VS Code has one built in (click to the left of a line number to set a breakpoint, then press F5), and so do the browser DevTools. See Debugging with DevTools for JavaScript.

Advanced: handling errors you expect

Some errors are not bugs but bad input, such as a user typing "eighty" for marks. You can catch an error and handle it instead of letting the program stop. Python uses try and except:

PythonRun it yourself
entries = ["88", "eighty", "92"]
for text in entries:
    try:
        marks = int(text)
        print("Saved:", marks)
    except ValueError:
        print(f"Skipped '{text}': not a whole number")
Output
Saved: 88
Skipped 'eighty': not a whole number
Saved: 92

JavaScript uses try and catch. Because Number("eighty") gives NaN instead of an error, the function below throws its own error when the value is not a number:

JavaScriptRun it yourself
function parseMarks(text) {
  const value = Number(text);
  if (Number.isNaN(value)) {
    throw new Error(`"${text}" is not a number`);
  }
  return value;
}

for (const text of ["88", "eighty", "92"]) {
  try {
    console.log("Saved:", parseMarks(text));
  } catch (error) {
    console.log("Skipped:", error.message);
  }
}
Output
Saved: 88
Skipped: "eighty" is not a number
Saved: 92

Catch only the errors you expect and know how to handle. Hiding every error makes real bugs much harder to find. You will learn more in Errors & Exceptions.

Common mistakes

  • Reading only the first line of a traceback. The useful part is at the bottom.
  • Changing many things at once. If it starts working, you will not know which change fixed it, and you may have added new bugs.
  • Assuming the bug is on the reported line. The cause is often a few lines earlier, where a value was created.
  • Forgetting to remove debug prints. Delete them, or the user will see DEBUG lines.

Key points

  • Syntax errors stop the program before it starts; runtime errors stop it at the failing line; logic errors give wrong answers silently.
  • Read a Python traceback from the bottom: error type and message first, then the code line and its line number.
  • JavaScript often gives undefined, NaN or Infinity instead of an error, so bugs appear later.
  • Use temporary print statements to see values and find logic errors.
  • Follow a checklist: read, print values, make it smaller, change one thing at a time.
  • Handle expected bad input with try/except (Python) or try/catch (JavaScript).

Exercise

This program should print the total marks and the percentage out of 300, but it has three bugs: one syntax error, one runtime error and one logic error. Find and fix all three, one at a time, running after each fix.

Python
marks = [72, 85, 64]
total = 0
for m in marks
    total += m
percentage = total / 300 * 10
print("Total:", totl)
print("Percentage:", percentage)
Show solution
Python
marks = [72, 85, 64]
total = 0
for m in marks:
    total += m
percentage = total / 300 * 100
print("Total:", total)
print("Percentage:", percentage)
Output
Total: 221
Percentage: 73.66666666666667

The syntax error is the missing colon after for m in marks. The runtime error is the misspelt totl (a NameError). The logic error is * 10 instead of * 100, which gave a percentage of about 7.4 without any error message.

Quick Quiz

1. Which kind of error lets the program run but gives a wrong answer?

2. Where should you start reading a Python traceback?

3. TypeError: Cannot read properties of undefined (reading 'length') means...

4. What is a good way to find a logic error?

Learn Intro to Programming with a mentor

Free lessons get you started. Our Python Programming training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call