Errors and Exceptions in Python


When you’re learning Python, you’re bound to run into errors. These come in two main types: syntax errors and exceptions.

Syntax Errors

Syntax errors, or parsing errors, happen when Python can’t understand your code. For example:

while True print('Hello world')

You’ll see something like this:

  File "<stdin>", line 1
    while True print('Hello world')
               ^^^^^
SyntaxError: invalid syntax

Here, Python highlights the spot where it got confused. It’s not always the actual mistake, but it helps narrow things down. In this case, the issue is a missing colon (:) after while True.

Exceptions

Even if your code is syntactically correct, it might still crash when something goes wrong during execution. These runtime errors are called exceptions.

Examples:

10 * (1 / 0)
# ZeroDivisionError: division by zero

4 + spam * 3
# NameError: name 'spam' is not defined

'2' + 2
# TypeError: can only concatenate str (not "int") to str

Each exception type describes what went wrong: dividing by zero, using an undefined name, or trying to mix strings and integers.

Handling Exceptions

You can write code to catch and handle exceptions gracefully using try and except. Here’s a basic example:

while True:
    try:
        number = int(input("Enter a number: "))
        break
    except ValueError:
        print("Oops! That wasn't a valid number. Try again...")

How this works:

  • The code inside try runs.
  • If it runs fine, except is skipped.
  • If an error occurs, Python jumps to the matching except block.
  • If no matching except is found, the program crashes.

You can have multiple except blocks:

try:
    # some risky code
except FileNotFoundError:
    print("File not found!")
except ValueError:
    print("Invalid value!")
except Exception as e:
    print(f"Unexpected error: {e}")
    raise

You can also catch multiple exceptions in a single block:

try:
    # code
except (TypeError, NameError):
    print("A type or name error occurred.")

Custom Exception Classes

You can define your own exception classes:

class MyError(Exception):
    pass

raise MyError("Something went wrong!")

Exceptions can carry extra data, too:

try:
    raise Exception("spam", "eggs")
except Exception as e:
    print(type(e))     # <class 'Exception'>
    print(e.args)      # ('spam', 'eggs')
    print(e)           # ('spam', 'eggs')
    x, y = e.args
    print("x =", x)
    print("y =", y)

Using else with try/except

You can run code if no exception occurs using else:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print("Cannot open file:", arg)
    else:
        print(arg, "has", len(f.readlines()), "lines")
        f.close()

finally: Cleanup No Matter What

The finally block is used for cleanup actions that must happen no matter what:

try:
    raise KeyboardInterrupt
finally:
    print("Goodbye, world!")

Even if an error happens or the user interrupts, the finally block runs.

More realistic example:

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("division by zero!")
    else:
        print("result is", result)
    finally:
        print("executing finally clause")

This will always print the finally message, whether an error occurs or not.

Using with for Automatic Cleanup

Instead of manually opening and closing files:

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

This way, the file is automatically closed, even if an error happens.

Raising Exceptions

You can raise exceptions yourself:

raise ValueError("Invalid input!")

To re-raise an exception after catching it:

try:
    raise NameError("HiThere")
except NameError:
    print("An exception flew by!")
    raise

Exception Chaining

If one error leads to another, you can chain them:

try:
    open("missing_file.txt")
except OSError as e:
    raise RuntimeError("Unable to handle error") from e

To suppress the original exception info:

try:
    open("missing_file.txt")
except OSError:
    raise RuntimeError from None

Multiple Unrelated Exceptions (Python 3.11+)

If you want to raise multiple unrelated exceptions at once:

def f():
    excs = [OSError("error 1"), SystemError("error 2")]
    raise ExceptionGroup("Multiple errors occurred", excs)

You can handle specific ones using except*:

try:
    f()
except* OSError:
    print("There were OSErrors")
except* SystemError:
    print("There were SystemErrors")

This is useful for async code, tests, or batch processing where multiple things can fail independently.


  • Related Posts

    Interactive Mode

    There are two variants of the interactive REPL in Python. The classic basic interpreter is supported on all platforms with minimal line control capabilities. On Windows, or Unix-like systems with…

    Read more

    Interactive Input Editing and History Substitution

    Some versions of the Python interpreter support editing of the current input line and history substitution, similar to facilities found in the Korn shell and the GNU Bash shell. This…

    Read more

    You Missed

    How Zoom Helps You Stay Safe in Cyberspace

    How Zoom Helps You Stay Safe in Cyberspace

    The Top 10 Webinar Platforms for Businesses in 2025

    The Top 10 Webinar Platforms for Businesses in 2025

    Enhancing Client Service: 5 Zoom Strategies for Professional Services Firms

    Enhancing Client Service: 5 Zoom Strategies for Professional Services Firms

    Understanding Omnichannel Customer Service

    Understanding Omnichannel Customer Service

    Zoom Set to Enhance Customer Experience with New Salesforce Service Cloud Voice Integration

    Zoom Set to Enhance Customer Experience with New Salesforce Service Cloud Voice Integration

    Leadership Strategies for Remote Teams