Lately I was reading about exception chaining, and i am not sure when i should use this syntax, and for what reason.
I am used to such pattern:
try:
my_function()
exception MyError:
my_logger.exception("Error occured")
raise MyProcessError("Process failed")
I have noticed that if I will use here exception chaining, one text in traceback will be changed, and MyProcessError will have new attribute with message from MyError.
try:
my_function()
exception MyError as err:
my_logger.exception("Error occured")
raise MyProcessError("Process failed") from err
The mention change in trace log is replacement of 'during handling of the above exception, another exception occured' to 'The above exception was the direct cause of the following exception'.
So what's the reason to use this syntax? When should I include it into my code? Examples are welcome :-)
In an exception handler, if you explicitly raise an exception you'll either want to use from err
or from None
(depending on if it makes more sense to suppress the original traceback or not).
Without from
, the message you get: "during handling of the above exception, another exception occurred", suggests "something went wrong, and then, while trying to recover from that, something else (possibly unrelated) went wrong. This is the case when you, for example make a typo (my_logger.expeption("Error occurred")
) or you try to save something to a file which can't be opened.
The with from
, it suggests that only a single thing went wrong, that you're not handling yourself but you have some more information that is of use to the programmer or user. For example, you can catch a KeyError
and raise a different exception with the message "tried to edit a non-existing widget" or whatever.
So raise SomeException("some description") from err
is a way to be able to explain what when wrong if the code that raised err
can't do that (because it is from the standard library or because it otherwise lacks the necessary context in which it is called), without having the user think that two separate things went wrong right after each other.