Python Academy · Lesson

Raising and Re-raising Exceptions

Use raise to signal errors and re-raise for propagation.

Lesson 3 of 414 steps

Raising and Re-raising Exceptions is a free Python Academy lesson on CoddyKit. This is lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Python Academy learning path, and your progress syncs across the web and the CoddyKit app. The Python Academy course includes 4 lessons in total.

Introduction

The raise keyword lets you signal errors explicitly. Re-raising preserves the original error context.

raise Built-in Exception

raise ValueError('message') immediately raises that exception type with the given message.
def divide(a, b):
    if b == 0:
        raise ValueError('Denominator cannot be zero')
    return a / b
try:
    divide(5, 0)
except ValueError as e:
    print(e)

Raising the Same Exception

Inside except, raise (with no argument) re-raises the current exception, preserving the original traceback.
def process(data):
    try:
        return int(data)
    except ValueError:
        print('logging error')
        raise  # re-raises original
try:
    process('abc')
except ValueError:
    print('caller caught it')

Exception Chaining with from

raise NewError('msg') from original chains the exceptions. exc.__cause__ is set.
try:
    int('abc')
except ValueError as original:
    raise RuntimeError('processing failed') from original

Suppressing Chaining

raise NewError() from None breaks the chain — the original exception is suppressed in the traceback.
try:
    int('abc')
except ValueError:
    raise RuntimeError('clean error') from None

assert Statement

assert condition, 'message' raises AssertionError if condition is False. Only for invariants during development.
def sqrt(x):
    assert x >= 0, f'Input must be non-negative, got {x}'
    return x ** 0.5
try:
    sqrt(-1)
except AssertionError as e:
    print(e)

Conditional Raise

Guard clauses with raise at the top of a function make preconditions explicit and avoid deep nesting.
def process(items):
    if not items:
        raise ValueError('items must not be empty')
    return items[0]
print(process([1, 2, 3]))

Re-raise vs New Exception

Re-raise (bare raise) preserves context. New exception hides it. Use chaining to keep both visible.
def outer():
    try:
        inner()
    except ValueError as e:
        raise RuntimeError('outer failed') from e
def inner():
    raise ValueError('inner failed')
try:
    outer()
except RuntimeError as e:
    print(e, e.__cause__)

Exception in finally

Raising in finally replaces the original exception. Avoid raising in finally unless absolutely necessary.
try:
    try:
        raise ValueError('original')
    finally:
        print('finally ran')
except ValueError as e:
    print('caught:', e)

warnings.warn vs raise

warn() for recoverable soft errors; raise for errors that must be handled. They serve different purposes.
import warnings
def old_func():
    warnings.warn('Deprecated', DeprecationWarning)
    return 42
print(old_func())

raise from None Pattern

When wrapping library exceptions into your own API exceptions, use from None to avoid leaking internal details.
class DBError(Exception): pass
def query(q):
    try:
        raise ConnectionError('refused')
    except ConnectionError:
        raise DBError('query failed') from None
try:
    query('SELECT 1')
except DBError as e:
    print(e)

Quick Check

What does 'raise' (with no argument) do inside an except block?

Recap

raise Type('msg') signals errors. Bare raise re-raises. raise New from Old chains. raise New from None suppresses context. assert for dev-time invariants.

Keep Going

Great work! Move on to the next lesson to keep progressing.
Free to start

Learn Python with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
76
Lessons
320

Frequently Asked Questions

Is the “Raising and Re-raising Exceptions” lesson free?

Yes — the full text of “Raising and Re-raising Exceptions” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Python Academy course, upgrade to CoddyKit PRO. The Python Academy course includes 4 lessons in total.

What will I learn in “Raising and Re-raising Exceptions”?

Use raise to signal errors and re-raise for propagation. You practise Python Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Python Academy?

No prior experience is required. Python Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.

How long does the “Raising and Re-raising Exceptions” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Python Academy lesson?

Yes. Every Python Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Understanding Exceptions
  2. try / except / else / finally
  3. Raising and Re-raising Exceptions
  4. Custom Exception Classes
← Back to Python Academy