Codectionary / Developer documentation / Python

raise

Signal a failure explicitly and let an appropriate caller choose how to recover.

Understand the contract

raise interrupts the normal sequence of statements by raising an exception. An enclosing try statement may handle it; otherwise it propagates through callers. This lets a low-level function report failure without deciding how a user interface should respond.

Choose a standard exception that describes the problem: ValueError for an unacceptable value of an otherwise suitable type, and TypeError for an unsupported type. Error messages should explain the violated condition rather than merely say that something failed.

Follow the runtime behavior

Code after raise in the same path is not executed. finally blocks still run while control leaves protected code. A bare raise inside an exception handler re-raises the active exception and preserves its traceback.

Catch only failures you can handle. A bare raise outside an active handler fails with RuntimeError, and raising an arbitrary string is invalid because exceptions must derive from BaseException.

Apply it and practise

Validate requirements near the boundary where they become meaningful. Let a reusable calculation raise an error and let its caller decide whether to retry, display a message, or abort.

Exercise: implement withdraw(balance, amount) with ValueError for a negative amount or an amount greater than balance. Catch the error at the caller and verify that valid withdrawals still return the remaining balance.

Syntax

raise ValueError("quantity must be positive")

Examples

Reject an invalid value

Use a clear failure for an impossible measurement rather than returning a misleading result.

def area(width: int) -> int:
    if width < 0:
        raise ValueError("width must be non-negative")
    return width * width

try:
    print(area(-2))
except ValueError as error:
    print(error)
print(area(3))
  1. The negative branch raises before multiplication. The handler prints the message, after which execution continues with an independent valid call.
  2. Use a clear failure for an impossible measurement rather than returning a misleading result.
  3. The hint alone does not validate types; this example only enforces the non-negative condition.
  4. Expected output: width must be non-negative 9

Re-raise after local handling

Use this pattern when local cleanup or recording is needed but the caller must still know the operation failed.

def parse(text: str) -> int:
    try:
        return int(text)
    except ValueError:
        print("parse failed")
        raise

try:
    parse("bad")
except ValueError:
    print("caller recovered")
  1. The inner handler records context and bare raise propagates the same active failure. The outer handler owns recovery, so no traceback escapes this script.
  2. Use this pattern when local cleanup or recording is needed but the caller must still know the operation failed.
  3. Avoid logging the same failure at every layer; the repeated records can obscure the one underlying event.
  4. Expected output: parse failed caller recovered

Clean up during failure

Use guaranteed cleanup for resources that must be released on both success and failure.

def work() -> None:
    try:
        print("start")
        raise RuntimeError("stopped")
    finally:
        print("cleanup")

try:
    work()
except RuntimeError as error:
    print(error)
  1. The finally suite runs as work exits exceptionally. Only after cleanup does the caller receive and print the original RuntimeError.
  2. Use guaranteed cleanup for resources that must be released on both success and failure.
  3. A new exception or return inside finally can mask the original outcome; keep cleanup simple.
  4. Expected output: start cleanup stopped

Best practices

  • Catch only failures you can handle. A bare raise outside an active handler fails with RuntimeError, and raising an arbitrary string is invalid because exceptions must derive from BaseException.
  • Validate requirements near the boundary where they become meaningful. Let a reusable calculation raise an error and let its caller decide whether to retry, display a message, or abort.

Runtime & versions

Python interpreter. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

Python language reference

Specifications & further reading