Raising Exceptions
00:00
In the previous lesson, I covered some of the attributes of the Exception
class. In this lesson, I’ll show you all the variations of how to use the raise
keyword and practice. At risk of repeating myself, exceptions typically get raised to signal an error, but you can also re-raise an exception.
00:19 You might do that if you want to perform a side effect in your error handling code, say, like doing some logging, but then still want the exception to happen.
00:29 Or, if you don’t like the exception you’re handling, you can raise your own instead. A common case for this is when using third-party libraries. The library might have its own exceptions or messages are too esoteric for your users, so you could raise your own clearer exception and message instead.
00:48 Let’s talk about some common cases where exceptions get raised. First is after a conditional check of some sort. This is like the bounds check in the grades example that I showed you in a previous lesson.
01:01 A second case is re-raising the exception. This is where you do something with the exception and then cause the exception to fire off anyways. And the third case is chaining exceptions together.
01:14 This is one way to relate multiple exceptions to each other. Let me head off to the REPL and I’ll show you a bit more about these last two. Once again, I’m dividing by zero. This time, I’ll add a note as well.
01:35
Using the raise
keyword on its own like this tells Python to re-raise the same exception that’s being handled within this block. This is a classic example of re-raising, doing something extra like logging or adding a note to the exception, then causing the exception to fire anyways. This is what it looks like when it runs.
01:55
You still get the traceback stack, but in addition to that, Python prints out the notes which got added to the exception after the ZeroDivisionError
line staring into the void.
02:05 in this case. Let’s do that again.
02:18
but this time I’m being more explicit about what I’m raising. I’m telling Python to explicitly raise the exception that was contained in the error
variable.
02:28
This is effectively the same as raise
on its own, but it gives you just a bit more information in the call stack. Note, the first time around you only got a single line in the stack, whereas this time you get a line for both where the exception happened and where it got re-raised. In practice, the difference here really doesn’t matter that much.
02:48 Let me define a custom exception
02:57
back to my dividing by zero use case and now instead of accepting the ZeroDivisionError
, I want to raise a MathError
instead.
03:11
Notice the information here. It says it was handling a ZeroDivisionError
and in doing so, another exception got raised, the MathError
.
03:20
Also note that since I passed the original error into the MathError
, the message from the ZeroDivisionError
got used to populate the message for the MathError
.
03:31 Alright, now let’s chain some stuff
03:43
and like before, I’m raising a different exception, but this time I’m using the from
keyword, which chains the two exceptions together.
03:53 Notice the difference in the output information from the first case. First case shows during error handling, whereas the second says the above exception was the cause of.
04:05
The from
keyword makes it a little more clear what happened. It’s a subtle difference, but it can be helpful.
04:23
Once again, I’m raising a new ValueError
, but this time I’m using from None
. This hides the ZeroDivisionError
altogether, which honestly is probably what you wanted in the first place.
04:36 Why would you be raising something new if you were happy about showing the original?
04:43 To finish up, a few guidelines about exceptions: try to use the right exception, favor something that fits your use over something more generic. Make sure to include a message and have the message be useful.
04:57
Something bad like I used in the last example probably isn’t so useful. Try to use Python’s own exceptions. Developers know what these are. I know why a ValueError
would get raised and you defining your own means now I have to go look up what yours means.
05:15 Try to raise your exception as early in the code as makes sense. Why eat up extra CPU cycles to discover a problem? And finally, document your code and include in your documentation any exceptions that you raise and why they might show up.
05:32 Next up, I’ll talk about assertions in Python and how they relate to exceptions.
Become a Member to join the conversation.