Reputation: 557
How do I raise a python exception with multiple causes, similar to Java's addSuppressed() feature? For example I have list of multiple methods to try and if none of them work I want to raise an exception that includes the exceptions from all the methods that were tried. I.e.:
exceptions = []
for method in methods_to_try:
try:
method()
except Exception as e:
exceptions.append(e)
if exceptions:
raise Exception("All methods failed") from exceptions
But this code fails because the raise ... from ...
statement expects a single exception and not a list. Python 2 or 3 solutions are acceptable. All back traces and exception messages must be preserved.
Upvotes: 6
Views: 1550
Reputation: 1568
Once could raise each exception from the other to chain it. The only issue is with the cause order which may be misleading.
def combine_exc(exceptions):
c_exc = None
for ex in reversed(exceptions):
try:
if c_exc is None:
raise ex
else:
raise ex from c_exc
except Exception as ex1:
c_exc = ex1
return c_exc
Upvotes: 1
Reputation: 12620
Just pass the exceptions as arguments when creating the last exception.
for method in methods_to_try:
try:
method()
except Exception as e:
exceptions.append(e)
if exceptions:
raise Exception(*exceptions)
They will be available en the args
attribute.
Upvotes: 3
Reputation: 2251
If using the logging module is acceptable for you, I guess it would be the cleanest to log the individual exceptions you caught and only raise a single overall exception.
If you only want to output the log-messages in case all tried functions error, this is an ideal case for the buffered logger from the logging cookbook You could modify it to always log at debug level, but raise the level to error, if all subfunctions raise an error.
Upvotes: 0