Errors, Exceptions and the Traceback
Quick answer A syntax error stops your program before a single line runs, while an exception is a runtime failure that Python raises as an object mid-execution — and only the second kind can be handled.
Every Python program can fail in two completely different ways, and the board expects you to tell them apart in one line.
A syntax error is a grammar mistake. Python reads and translates your whole file first; if the grammar is broken it refuses to start. Save this as syntaxdemo.py:
print("Line 1 runs fine")
if marks > 40
print("Pass")Running it produces no program output at all:
File "syntaxdemo.py", line 2
if marks > 40
^
SyntaxError: expected ':'Look very carefully at what is missing. The words Line 1 runs fine never appeared. That print on line 1 is perfectly valid Python, but it never ran, because the file never finished compiling. That is the fingerprint of a syntax error, and no amount of try and except can rescue it. You fix the missing colon and move on.
An exception is a different animal. The grammar is fine, the program starts, lines execute — and then it dies part-way through because of the actual values it met. Save this as marks.py:
marks = 450
total = 0
print("Percentage:", marks / total)
print("This line never runs")The real output:
Traceback (most recent call last):
File "marks.py", line 3, in
print("Percentage:", marks / total)
~~~~~~^~~~~~~
ZeroDivisionError: division by zeroNothing is wrong with that code as text. Divide 450 by 5 and it works fine. It only broke because total happened to hold 0 at that moment. That is exactly why exceptions are worth handling: the same correct code is safe with good data and fatal with bad data, and bad data is normal — a user types ninety instead of 90, a file has been renamed, a roll number is missing from a dictionary.
How to read a traceback. Students waste minutes reading it top-down. Read it bottom-up:
- The last line is the answer. It gives the exception class (
ZeroDivisionError) and the reason (division by zero). - The line above it shows the exact statement, with
~~~^~~~markers pointing at the sub-expression that blew up. Here the markers sit undermarks / total, not under the wholeprint. - The
File "...", line 3line tells you where to go and fix it.
The words Traceback (most recent call last) at the top mean the list is oldest-call-first, so the place that actually failed is at the bottom. Everything above the last line is context.
Exceptions are objects, not just messages. Each one belongs to a built-in class, and it is that class name you will write after except. Every message in the table below was copied from an actual run — none of it is paraphrased:
| Exception class | Code that raises it | Message Python printed |
|---|---|---|
| ZeroDivisionError | 10 / 0 | division by zero |
| ValueError | int("abc") | invalid literal for int() with base 10: 'abc' |
| TypeError | "Rs " + 500 | can only concatenate str (not "int") to str |
| IndexError | [10, 20, 30][5] | list index out of range |
| KeyError | {"Aarav": 88}["Diya"] | 'Diya' |
| FileNotFoundError | open("fees.txt") | [Errno 2] No such file or directory: 'fees.txt' |
| NameError | totl_marks | name 'totl_marks' is not defined |
| AttributeError | "88".upperr() | 'str' object has no attribute 'upperr' |
Two of these are worth a second look because students confuse them constantly. ValueError means the type was acceptable but the value was not — int() is happy to take a string, it just cannot make a number out of "abc". TypeError means the type itself was wrong for the operation, like trying to glue an int onto a str.
Also note KeyError versus IndexError. A missing dictionary key gives KeyError; an out-of-range list or string position gives IndexError. Writing the wrong one in an except clause means your handler silently never fires.
- A syntax error is caught while Python is translating the file, so the program never starts — proven by the fact that print("Line 1 runs fine") produced no output before the SyntaxError. It cannot be handled with try-except; you fix the code.
- An exception happens at runtime, after the program has started, and depends on the actual data — marks / total is fine until total is 0.
- Read a traceback from the bottom up: the last line names the exception class and the reason, and the ~~~^~~~ markers point at the exact sub-expression that failed.
- Every exception is an object of a built-in class, and that class name is what you write after except — get it wrong and your handler never runs.
- ValueError = right type, impossible value (int("abc")). TypeError = wrong type for the operation ("Rs " + 500). KeyError is for dictionaries, IndexError for lists and strings.
