In my code I want to catch an exception when it occurs, print some information abut the exception to the screen, and then end the script once I have done so. I tried to use something equivalent to the following code, but I don't understand why I get the traceback I do.
When executing:
try:
1 / 0
except ZeroDivisionError:
print("Exception: ZeroDivisionError")
raise Exception
Console reads:
Exception: ZeroDivisionError
Traceback (most recent call last):
File "<pyshell#19>", line 2, in <module>
1 / 0
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#19>", line 5, in <module>
raise Exception
Exception
I thought that if I catch the ZeroDivisionError
, it would no longer be raised, and the only thing that would show is the raise Exception
I do at the end, but both show in the console.
Why do they both show, and how do I alter the code so only the second shows, or is there a better way to achieve what I want?
You can also handle multiple exceptions using a single except clause by passing these exceptions to the clause as a tuple . except (ZeroDivisionError, ValueError, TypeError): print ( "Something has gone wrong.." ) Finally, you can also leave out the name of the exception after the except keyword.
A try statement may have more than one except clause, to specify handlers for different exceptions. At most one handler will be executed. Handlers only handle exceptions that occur in the corresponding try clause, not in other handlers of the same try statement.
Can one block of except statements handle multiple exception? Answer: a Explanation: Each type of exception can be specified directly. There is no need to put it in a list.
Use pass to ignore an exception Within a try and except block, use pass in the except clause to indicate no action is required in handling the caught exception.
The console shows the context here; when an exception is raised from an exception handler, Python attaches the active exception as the __context__
attribute and Python shows that context later on if the new exception is not being handled. If you don't want the context to be shown, you need to supply a cause instead; you can supply an empty cause with with raise ... from None
:
try:
1 / 0
except ZeroDivisionError:
print("Exception: ZeroDivisionError")
raise Exception from None
Quoting the raise
statement documentation:
The
from
clause is used for exception chaining: if given, the second expression must be another exception class or instance, which will then be attached to the raised exception as the__cause__
attribute (which is writable). If the raised exception is not handled, both exceptions will be printed[...]A similar mechanism works implicitly if an exception is raised inside an exception handler: the previous exception is then attached as the new exception’s
__context__
attribute[...]
And from the Exceptions documentation:
When raising (or re-raising) an exception in an
except
clause__context__
is automatically set to the last exception caught; if the new exception is not handled the traceback that is eventually displayed will include the originating exception(s) and the final exception.When raising a new exception (rather than using a bare
raise
to re-raise the exception currently being handled), the implicit exception context can be supplemented with an explicit cause by usingfrom
withraise
:raise new_exc from original_exc
The expression following from must be an exception or
None
. It will be set as__cause__
on the raised exception. Setting__cause__
also implicitly sets the__suppress_context__
attribute toTrue
, so that usingraise new_exc from None
effectively replaces the old exception with the new one for display purposes (e.g. convertingKeyError
toAttributeError
), while leaving the old exception available in__context__
for introspection when debugging.The default traceback display code shows these chained exceptions in addition to the traceback for the exception itself. An explicitly chained exception in
__cause__
is always shown when present. An implicitly chained exception in__context__
is shown only if__cause__
is None and__suppress_context__
is false.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With