Zakru
Zakru

Reputation: 92

Python equivalent of Java Exception with cause

Is there a way in Python to raise an error that has another error as its cause?

In Java, you can create an instance of an exception with a cause such as in the following code

try {
    throw new IOException();
} catch (IOException e) {
    throw new RuntimeException("An exception occurred while trying to execute", e);
}

resulting in in this error message:

Exception in thread "main" java.lang.RuntimeException: An exception occurred while trying to execute
    at thing.Main.main(Main.java:11)
Caused by: java.io.IOException
    at thing.Main.main(Main.java:9)

Notice that the first exception (in the stack trace) is "caused by" the second.

This is, in my opinion, a great way to show an API user that a higher-level error occurred during a call, and the developer can debug it by looking at the lower-level exception which is the "cause" of the higher-level error (in this case the RuntimeException is caused by the IOException).

With the searches I've made, I haven't been able to find anything about having an error as the cause of another in Python. Can this be achieved in Python? How? And if not, what would be a Pythonic equivalent?

Upvotes: 3

Views: 940

Answers (1)

DeepSpace
DeepSpace

Reputation: 81654

In Python it is achieved by a very similar structure:

try:
    raise ValueError
except ValueError:
    raise ValueError('second exception')

This will generate the following traceback:

Traceback (most recent call last):
  File "main.py", line 2, in <module>
    raise ValueError
ValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 4, in <module>
    raise ValueError('second exception')
ValueError: second exception

Another Python feature is raise from which provide a slightly different traceback:

try:
    raise ValueError
except ValueError as e:
    raise ValueError('second exception') from e

Traceback:

Traceback (most recent call last):
  File "main.py", line 2, in <module>
    raise ValueError
ValueError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "main.py", line 4, in <module>
    raise ValueError('second exception') from e
ValueError: second exception

Further reading:

Upvotes: 4

Related Questions