Syntax errors vs exceptions

A syntax error means Python cannot even parse the file — a missing colon or bracket — and nothing runs. An exception happens while the program runs: dividing by zero, opening a file that is missing, converting "abc" to an int. Unhandled, an exception stops the program and prints a traceback. Learning to read a traceback is the single most useful debugging skill:

numbers = [1, 2, 3]
print(numbers[5])
Traceback (most recent call last): File "main.py", line 2, in <module> print(numbers[5]) IndexError: list index out of range

Read it from the bottom up: the last line names the exception type and message; the lines above show exactly where it happened.

try and except

while True:
    raw = input("Enter a number: ")
    try:
        value = float(raw)
        break
    except ValueError:
        print(f"'{raw}' is not a number, try again.")

print("Doubled:", value * 2)
Enter a number: abc 'abc' is not a number, try again. Enter a number: 4.5 Doubled: 9.0

Python runs the try block; if the named exception occurs, it jumps to except and continues afterwards instead of crashing. Always catch the specific type you expect — a bare except: silently hides bugs you did not anticipate.

Multiple exceptions, else and finally

def safe_divide(a, b):
    try:
        result = a / b
    except ZeroDivisionError:
        print("Cannot divide by zero")
        return None
    except TypeError as err:
        print("Bad input:", err)
        return None
    else:
        print("Division succeeded")   # runs only if no exception
        return result
    finally:
        print("-- done --")           # ALWAYS runs

print(safe_divide(10, 2))
print(safe_divide(1, 0))
print(safe_divide("a", 2))

try:
    int("x")
except (ValueError, TypeError):      # several types at once
    print("conversion failed")
Division succeeded -- done -- 5.0 Cannot divide by zero -- done -- None Bad input: unsupported operand type(s) for /: 'str' and 'int' -- done -- None conversion failed

finally is for clean-up that must happen no matter what — closing files, releasing locks. as err gives you the exception object so you can log its message.

Common built-in exceptions

ExceptionTypical cause
ValueErrorRight type, wrong value: int("abc")
TypeErrorWrong type: "a" + 1, calling a non-function
KeyErrorMissing dictionary key
IndexErrorList index out of range
ZeroDivisionErrorDividing by zero
NameErrorUsing a variable that does not exist (often a typo)
AttributeErrorObject has no such method/attribute: [].push(1)
FileNotFoundErrorOpening a path that does not exist
ImportError / ModuleNotFoundErrorModule not installed or misspelled
RecursionErrorRecursion with no base case

The guide to common Python errors and how to fix them walks through each with real examples.

Raising exceptions

def set_age(age):
    if not isinstance(age, int):
        raise TypeError("age must be an int")
    if age < 0:
        raise ValueError(f"age cannot be negative, got {age}")
    return age

try:
    set_age(-3)
except ValueError as e:
    print("Rejected:", e)

# re-raise after logging
try:
    set_age("ten")
except TypeError:
    print("logging the problem...")
    # raise   # uncomment to propagate
Rejected: age cannot be negative, got -3 logging the problem...

Custom exceptions

class InsufficientFunds(Exception):
    def __init__(self, needed, available):
        super().__init__(f"need {needed}, have {available}")
        self.needed, self.available = needed, available

def withdraw(balance, amount):
    if amount > balance:
        raise InsufficientFunds(amount, balance)
    return balance - amount

try:
    withdraw(50, 80)
except InsufficientFunds as e:
    print("Error:", e, "| short by", e.needed - e.available)
Error: need 80, have 50 | short by 30

Custom exceptions let callers catch your library's errors specifically. Subclass Exception, never BaseException.

Practise try/except with the app's error-handling example — the Coding Python app runs real Python 3 on your phone, with examples, quizzes and challenges built in.
Get it free

Exceptions vs checking first

Python culture favours EAFP — "easier to ask forgiveness than permission": just try the operation and handle the exception. It is often faster and avoids race conditions (a file that exists when you check may be gone when you open it). Use if key in d style checks when the failure case is common and cheap to detect.

Next: reading and writing files, where exceptions are a daily companion — file handling.

Frequently asked questions

What is the difference between an error and an exception in Python?

Syntax errors stop the program before it runs. Exceptions are runtime errors that can be caught and handled with try/except so the program continues.

Should I use a bare except: in Python?

No. except: catches everything including KeyboardInterrupt and hides real bugs. Catch specific types, or at minimum except Exception as e and log e.

What does finally do?

The finally block runs whether or not an exception occurred, even if there is a return inside try. Use it to close files or release resources.

How do I raise an exception in Python?

Use raise followed by an exception instance: raise ValueError('message'). Inside an except block, a bare raise re-raises the current exception.