Re-raising Exceptions in Python: Logging Errors and Notifying the Caller

When implementing exception handling (try-except), there are cases where you don’t want to “resolve the error on the spot,” but rather “log the fact that an error occurred and leave the actual handling to the caller (higher-level process).”

In such cases, “Re-raising” the exception is effective. By intentionally raising the captured exception again, you can propagate the error information to the upper level without suppressing it.

This article explains how to re-raise exceptions using the raise statement and how to correctly preserve the traceback (information about where the error occurred).


目次

What is Re-raising?

When an exception is caught in a try-except block, the error is usually considered “resolved” there, and the program continues with subsequent processing. However, for critical errors occurring within a function, you often need to notify the side calling the function that “an error has occurred,” rather than completing the process within the function itself. At this time, you use the raise statement inside the except block.


The Correct Way to Re-raise: raise Without Arguments

When re-raising an exception, the most recommended method is to write raise alone without specifying any arguments.

Syntax:

try:
    # Processing
except Exception:
    # Log output, etc.
    raise  # Re-raise the caught exception as is

Specific Example

Let’s take a function that reads a configuration value and converts it to a number as an example. If the conversion fails, it outputs an error log and re-raises the exception to notify the entire system of the abnormality.

def parse_configuration(config_value):
    """
    Function to convert configuration value to integer
    """
    try:
        # Convert string to integer (ValueError if failed)
        result = int(config_value)
        return result

    except ValueError:
        # 1. Detect error here and output log
        print(f"[Log] Failed to convert config value. Value: {config_value}")
        
        # 2. Re-raise the exception (Notify caller of error)
        raise

# --- Main Processing ---
print("Starting process.")

try:
    # Pass invalid value (string) to execute function
    value = parse_configuration("InvalidNumber")
    
except ValueError:
    # 3. Catch the re-raised exception at the caller
    print("[System] Processing interrupted due to config error.")

print("Process finished.")

Output:

Starting process.
[Log] Failed to convert config value. Value: InvalidNumber
[System] Processing interrupted due to config error.
Process finished.

This flow achieves both “logging within the function” and “error handling (interruption) at the caller.”


Difference Between raise e and raise

It is possible to receive the exception object in a variable and re-raise it like raise e.

    except ValueError as e:
        print("Logging")
        raise e  # Specify variable to re-raise

However, if you simply want to throw the original exception upwards, using raise without arguments is recommended.

  • raise (no arguments): Preserves the “traceback (history such as line numbers where the error occurred)” of the generated exception as is. It makes the initial error location clear during debugging.
  • raise e: Depending on the situation and Python version, the traceback information might be overwritten or treated as a chained exception, making it potentially harder to trace where the initial error occurred (unless that is your specific intent).

Summary

  • Use “Re-raising” when you want to perform logging or temporary cleanup after catching an exception, but want to leave the error handling itself to the upper-level process.
  • You can re-raise the currently caught exception as is by simply writing raise inside the except block.
  • This allows you to propagate error information while accurately maintaining the error location (traceback).
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次