How to rethrow Python exception with new type?

In Python, you can catch an exception and raise a new one, while keeping the original exception for more details. This helps when you want to change a low-level error into a clearer, higher-level error that fits your application better.

Sometimes, catching a specific exception and raising a new one helps you to handle problems or give a clearer message. Python lets you do this using the raise NewException from OriginalException syntax.

Rethrowing with a New Exception Type

You can rethrow an exception using the from keyword to keep the original error details and traceback. This helps you provide a new error while still showing where the original problem happened ?

Example: Converting ZeroDivisionError to ValueError

In this example, we catch a ZeroDivisionError and raise a ValueError instead, keeping the original exception context ?

def divide(a, b):
    try:
        return a / b
    except ZeroDivisionError as e:
        raise ValueError("Division failed due to zero denominator") from e

try:
    result = divide(10, 0)
except ValueError as e:
    print("Caught ValueError:", e)
    print("Original cause:", e.__cause__)

Here, the new exception provides a clearer message, but the original cause is still accessible using e.__cause__ attribute ?

Caught ValueError: Division failed due to zero denominator
Original cause: division by zero

Rethrowing Without Preserving Original Exception

You can raise a new exception without linking it to the original error by omitting the from keyword. This means the new error will appear on its own, without showing the original traceback ?

Example

In this example, we replace the original exception but don't keep a reference to it ?

def parse_number(s):
    try:
        return int(s)
    except ValueError:
        raise TypeError("Expected a numeric string")

try:
    result = parse_number("abc")
except TypeError as e:
    print("Caught TypeError:", e)

In this case, only the new exception is shown. The original ValueError is not accessible ?

Caught TypeError: Expected a numeric string

Suppressing Original Exception with 'from None'

To completely hide the original exception and its traceback, use raise NewException from None. This creates a clean error without any reference to the original cause ?

def safe_divide(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        raise ValueError("Cannot divide by zero") from None

try:
    result = safe_divide(10, 0)
except ValueError as e:
    print("Clean error:", e)
    print("Original cause:", getattr(e, '__cause__', 'None'))
Clean error: Cannot divide by zero
Original cause: None

Comparison

Method Preserves Original? Use Case
raise NewError from e Yes (__cause__) Debug-friendly, keeps context
raise NewError Partially (__context__) Simple replacement
raise NewError from None No Clean user-facing errors

Conclusion

Use from exception to preserve debugging context, from None for clean user errors, and plain raise for simple exception replacement. Choose based on whether you need the original error details for debugging.

Updated on: 2026-03-24T16:29:02+05:30

504 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements