VMware ESXi and vSphere Cluster Management

How to Raise Exceptions in Python

Learn how to use Python's raise statement to validate values, choose exception types, write useful messages, and handle raised exceptions with try and except.

What Is an Exception?

An exception is an event representing an error or abnormal condition that changes the normal control flow of a program. Normal control flow is the ordinary sequence in which statements execute when nothing interrupts them.

Python raises some exceptions automatically. For example, dividing by zero produces a ZeroDivisionError, and converting an invalid string to an integer can produce a ValueError. You can also raise an exception yourself when your program detects a condition that violates a rule.

Manually raising an exception is useful for enforcing requirements early. For example, a function can reject a number below a minimum instead of continuing with invalid data.

The raise Statement

The raise keyword manually triggers an exception. Its basic form is:

raise ExceptionType

For example:

raise ValueError

This statement creates and raises a ValueError. Unless a matching handler catches it, execution stops at the raise statement. Statements later in the current block do not run.

You can also raise an exception with a descriptive message:

raise ValueError("The quantity must be greater than zero")

The text in parentheses is an exception message: optional explanatory text attached to the exception instance. If the exception is not caught, Python displays this message with the exception type.

Choosing an Exception Type

The exception type should communicate what went wrong. Exception types are part of a function's behavior: callers can use them to handle different problems precisely.

Exception typeWhen to raise itExample invalid condition

ValueError — The value has an acceptable general type but an unacceptable value — A numeric age is negative or outside an allowed range.

TypeError — An argument has an unsupported type — A function requires a number but receives a list.

KeyError — A requested key is not present in a mapping such as a dictionary — Code requires the key "username", but that key is absent.

IndexError — A sequence index is outside the available range — Code requests item 5 from a list containing only three items.

RuntimeError — A general runtime condition prevents an operation and no more specific built-in exception fits — An object is in an unusable state for the requested operation.

Use ValueError when the type is generally right but the value breaks a rule. Use TypeError when the kind of object is wrong. Prefer a more specific exception when one clearly describes the problem.

Validating a Number with ValueError

A common pattern is to check a value with an if statement and raise an exception when the check fails:

minimum_age = 18
age = 15

if age < minimum_age:
    raise ValueError(
        f"age must be at least {minimum_age}; received {age}"
    )

print("Age accepted")

Here, age < minimum_age is the failed condition. Because the condition is true for 15, Python raises ValueError. The final print() call is never reached unless the exception is handled somewhere.

A useful message identifies the violated rule and, when appropriate, the received value. Messages such as "invalid input" provide less help than "age must be at least 18; received 15".

Putting Validation in a Function

Validation is often placed at the boundary of a function so invalid state cannot travel farther into the program:

def set_quantity(quantity):
    minimum_quantity = 1

    if quantity < minimum_quantity:
        raise ValueError(
            f"quantity must be at least {minimum_quantity}; "
            f"received {quantity}"
        )

    return quantity

valid_quantity = set_quantity(3)
print(valid_quantity)

With 3, the condition is false, so the function continues and returns the value. With 0, it raises ValueError before returning.

Raising and Catching an Exception

A try block contains code that may raise an exception. An except block handles a matching exception:

try:
    raise ValueError("The supplied value is not acceptable")
except ValueError as error:
    print(f"Could not continue: {error}")

The manually raised ValueError matches except ValueError. Python transfers control to the handler, which prints a controlled user-facing message. The program does not display an unhandled traceback for this exception.

A handler is useful only where the program can meaningfully report, recover from, translate, or log the problem. Catching an exception does not make the original condition valid; it determines how the program responds to it.

Handling Valid and Invalid Values

def check_score(score):
    if score < 0 or score > 100:
        raise ValueError(
            f"score must be between 0 and 100; received {score}"
        )
    return score

for score in (85, 120):
    try:
        accepted_score = check_score(score)
        print(f"Accepted: {accepted_score}")
    except ValueError as error:
        print(f"Rejected: {error}")

The value 85 satisfies the rule and follows normal execution. The value 120 violates the rule, so check_score() raises ValueError. The caller catches it and reports the problem separately.

Specific Exception Handling

Catch the narrowest exception type that your code expects to handle. A specific handler documents the intended failure and avoids hiding unrelated programming errors.

try:
    amount = int("not a number")
except ValueError:
    print("Please enter a whole number")

A bare except: catches almost everything, including exceptions that may indicate a bug or an interruption. It can make failures difficult to diagnose. Prefer except ValueError when the known problem is invalid numeric input.

Different exception types can have separate handlers:

try:
    item = records["name"]
    position = items[10]
except KeyError:
    print("The required record field is missing")
except IndexError:
    print("The requested item does not exist")

Each handler gives a different response because the underlying problems differ.

Tracebacks and Unhandled Errors

A traceback is diagnostic output showing where an unhandled exception occurred. It commonly includes:

  • The traceback heading and the sequence of calls that led to the failure.
  • The file name and line number where the current call is located.
  • The source line associated with the failure.
  • The exception type, such as ValueError.
  • The exception message, such as "score must be between 0 and 100; received 120".

For example, this code has no handler:

minimum = 10
value = 4

if value < minimum:
    raise ValueError(f"value must be at least {minimum}; received {value}")

Python stops the program at raise and displays a traceback ending with the exception type and message. A traceback is diagnostic information, not normal successful output. The message makes the failure easier to understand and debug.

How Raised Exceptions Affect Program Execution

SituationWhat Python doesWhat the user or developer sees

Raised exception with matching except handler — Stops the try block and runs the matching handler — A controlled recovery or reporting message.

Raised exception without a matching handler — Stops the current flow and propagates the exception to the caller; if nobody handles it, the program terminates — An unhandled traceback containing the location, exception type, and message.

Validation condition does not fail — Does not execute raise; subsequent statements continue normally — Normal program output.

Good Practices for Raising Exceptions

  • Raise early: Raise the exception at the point where invalid input or invalid state is detected.
  • Choose precisely: Use the most meaningful built-in exception type, such as ValueError for an unacceptable value or TypeError for an unsupported type.
  • Write actionable messages: State the requirement, the received value when safe and useful, and what the caller should correct.
  • Do not use exceptions for ordinary control flow: If a simple conditional clearly handles an expected choice, use the conditional instead of raising and catching an exception.
  • Catch where recovery is possible: Handle an exception at the layer that can meaningfully recover, translate the error, log it, or show an appropriate message.
  • Avoid broad handlers: Do not use a bare except to hide unknown failures when a specific exception type is expected.

Troubleshooting Raised Exceptions

A Traceback Appears Instead of a Recovery Message

The exception may not be inside a try block with a matching handler, or the handler may catch the wrong type. Catch the specific exception where recovery is appropriate. A traceback can remain appropriate for a developer-facing failure that the program cannot meaningfully handle.

A ValueError Is Raised for a Value That Seems Valid

Inspect the conditional expression, the threshold, and the actual value supplied. The comparison may be reversed or the allowed boundary may be incorrect. Include received and expected values in the message to make the mismatch visible.

The except Block Does Not Run

The exception type raised does not match the type named by except, or the exception occurred outside the relevant try block. Use a matching exception class or add a separate handler for the intended type.

The Error Message Is Too Vague

Replace generic text with a concise statement of the violated requirement. For example, prefer "temperature must be at least -20; received -35" over "bad input".

A Broad Handler Hides Bugs

A bare except, or an unnecessarily broad except Exception, may conceal unrelated errors. Catch the narrowest relevant type, such as ValueError, and let unexpected failures remain visible during development.

Summary

  • raise manually interrupts normal control flow by triggering an exception.
  • Use ValueError when a value has a suitable general type but violates an accepted-value rule.
  • Attach a concise message that explains the requirement and, when useful, the received value.
  • Place risky or validating code in try and handle known failures with a matching specific except clause.
  • An unhandled exception produces a traceback containing diagnostic location, type, and message information.

For a focused reference on this topic, see raising exceptions in Python.