Python Exceptions: Try, Except, and Raise

Boot.dev Blog » Python » Python Exceptions: Try, Except, and Raise
Lane Wagner
Lane Wagner

Last published March 8, 2026

Table of Contents

Python has two kinds of errors: syntax errors that prevent your code from running at all, and exceptions that happen while your code is executing. Knowing how to handle exceptions with try/except and how to raise your own is a core skill for writing reliable programs.

All the content from our Boot.dev courses are available for free here on the blog. This one is the “Errors” chapter of Learn to Code in Python. If you want to try the far more immersive version of the course, do check it out!

What Is the Difference Between Syntax Errors and Exceptions?

A syntax error means your code isn’t valid Python. The interpreter can’t even run it:

prnt("hello world)
File "<python-input-0>", line 1
  prnt("hello world)
       ^
SyntaxError: unterminated string literal (detected at line 1)

An exception is different. Your code is valid Python, but something goes wrong during execution. For example, dividing by zero is syntactically fine — Python just can’t produce a result:

print(10 / 0)
# ZeroDivisionError: division by zero

Syntax errors must be fixed before you can run your program. Exceptions can be caught and handled gracefully so your program doesn’t crash.

How Does Try/Except Work in Python?

Python uses a try/except pattern for handling exceptions. The try block runs until an exception is raised or it completes, whichever happens first. The except block only executes if an exception is raised:

try:
    10 / 0
except Exception:
    print("can't divide by zero")

If you want to access the data from the exception, use the as keyword:

try:
    10 / 0
except Exception as e:
    print(e)  # division by zero

Wrapping risky code in try/except blocks lets the program handle the problem without crashing. This is especially useful when working with user input, dictionary lookups, or list indexing — any operation where bad data might sneak in at runtime.

How Do You Raise Exceptions in Python?

Errors are not something to be scared of. Every program that runs in production manages errors on a constant basis. When something in your own code isn’t the “happy path”, you should raise an exception to let the caller know something went wrong:

def craft_sword(metal_bar):
    if metal_bar == "bronze":
        return "bronze sword"
    if metal_bar == "iron":
        return "iron sword"
    if metal_bar == "steel":
        return "steel sword"
    raise Exception("invalid metal bar")

The raise keyword stops execution and forces the exception to be handled by the caller. This prevents bugs — if a function receives input it can’t work with, raising an exception is better than silently returning garbage.

An error is raised when something bad happens, but as long as your code handles it as users expect, it’s not a bug. A bug is when code behaves in ways users don’t expect.

Don’t catch your own exceptions

As a rule of thumb, don’t catch exceptions you raise within the same function:

# don't do this
def craft_sword(metal_bar):
    try:
        if metal_bar == "bronze":
            return "bronze sword"
        raise Exception("invalid metal bar")
    except Exception as e:
        print(f"An error occurred: {e}")

The caller should handle the error:

try:
    craft_sword("gold bar")
except Exception as e:
    print(e)  # invalid metal bar

This keeps your functions focused on one job and lets each layer of code decide how to respond to failures.

What Are the Different Exception Types in Python?

Not all exceptions are the same. Python has a hierarchy of built-in exception types, each describing a specific kind of problem:

You can catch specific exception types instead of the generic Exception:

try:
    nums = [0, 1]
    print(nums[2])
except IndexError:
    print("index error")
except Exception as e:
    print(e)

This prints index error because the IndexError handler matches first.

How Do You Catch Specific Exceptions in Python?

When handling exceptions, catch the most specific type first. Python stops checking once it finds a matching handler. If you catch a general Exception first, specific handlers below it will never run:

# wrong order — IndexError never gets caught specifically
try:
    nums = [0, 1]
    print(nums[2])
except Exception:
    print("An error occurred")
except IndexError:
    print("Index error")

The general Exception catches everything, so the IndexError branch is dead code. Always order your except clauses from most specific to most general:

try:
    nums = [0, 1]
    print(nums[2])
except IndexError:
    print("Index error")
except Exception as e:
    print(e)

Catching specific exceptions makes your code easier to debug and prevents you from accidentally swallowing errors you didn’t expect. This matters more as your programs grow — a generic except Exception might hide a bug in your loop logic or a typo in a variable name.

What Should You Learn After Python Exceptions?

Error handling is one of those skills that separates code that works from code that works reliably. Now that you understand try/except and raise, you’re ready to write programs that fail gracefully instead of crashing.

From here, most beginners move on to learning about sets or dive deeper into functions and code organization. If you want to keep going through the full Python curriculum with hands-on exercises, check out the Learn to Code in Python course on Boot.dev.

Frequently Asked Questions

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

A syntax error means your code is not valid Python and cannot run at all. An exception happens during execution when something goes wrong, like dividing by zero or accessing an invalid index. Syntax errors must be fixed before running. Exceptions can be caught and handled gracefully with try/except.


Should you catch all exceptions with a bare except clause?

No. Catching all exceptions with a bare except or except Exception hides bugs and makes debugging harder. Catch the most specific exception type you can so that unexpected errors still surface.


What is the difference between raise and return in Python?

return sends a value back to the caller and continues normal execution. raise stops normal execution and forces the caller to handle the error with a try/except block. Use raise when something has gone wrong and the function cannot produce a valid result.


Can you raise exceptions inside a try block?

Yes, you can raise exceptions anywhere, including inside a try block. If the raised exception matches an except clause in the same try block it will be caught there. However, as a rule of thumb, avoid catching exceptions you raise within the same function.