Using raise for Effective Exceptions (Summary)
In your Python journey, you’ll come across situations where you need to signal that something is going wrong in your code. For example, maybe a file doesn’t exist, a network or database connection fails, or your code gets invalid input. A common approach to tackle these issues is to raise an exception, notifying the user that an error has occurred. That’s what Python’s raise
statement is for.
Learning about the raise
statement allows you to effectively handle errors and exceptional situations in your code. This way, you’ll develop more robust programs and higher-quality code.
In this video course, you’ll learn how to:
- Raise exceptions in Python using the
raise
statement - Decide which exceptions to raise and when to raise them in your code
- Explore common use cases for raising exceptions in Python
- Apply best practices for raising exceptions in your Python code
Congratulations, you made it to the end of the course! What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment in the discussion section and let us know.
00:00 In the previous lesson, I explained exception groups. In this lesson, I’ll summarize the course. Exceptions give you a way of interrupting the flow of your code and typically get used for error processing.
00:14
Exceptions are objects and inherit from the Exception
class, and you can write custom exceptions simply by creating your own class, which inherits from this as well.
00:26
When handling an exception, you can use the raise
keyword to re-raise the same exception, or you can raise a different exception instead. By using the from
keyword, you can chain exceptions together or bury the original exception by raising from None
.
00:45
Finally, you learned about the new ExceptionGroup
feature added in Python 3.11. This allows you to raise a collection of exceptions and you use the except*
syntax to handle a single exception from within a group.
01:01 That’s all for me. I hope you found this course useful. Thanks.
Michael Gaunt on April 16, 2024
Exceptions groups look cool!
Christopher Trudeau RP Team on April 17, 2024
Thanks folks, glad you enjoyed the course.
Yep, I find I use built-in exceptions the majority of the time. I only tend to create custom ones if I truly need to express something original.
As for the groups, yeah, they’re neat. I’ve yet to use them in real life, but handy to have when the need arises.
gary391 on Aug. 11, 2024
Great tutorial!!
This is reference a script which does the following task.
Function A, calls an API 1 to GET the data 1 - Service 1 Function B, calls an API 2 to GET the data 2 - Service 2 Function C, using the data 1, 2 does a POST to update values - Service 3
The Function A, B, C are being called on a list items.
What will be a good strategy to handle exception in the above scenario?
- Catching the exception using a try and except at the individual function level or in the main function?
- What will be the good approach to handle exception being passed between different functions ?
Any pointers are much appreciated?
Christopher Trudeau RP Team on Aug. 11, 2024
Hi Gary,
When you’ve got multiple things that can raise exceptions like in your example, the question you need to ask yourself is: what are you going to do if there is an exception? In the example you gave, I suspect, all three things have to work, or nothing is going to work. If, for example, the only thing you want is a pretty error for your users instead of the exception propagating all the way up, then you really only have to catch things at the outside level.
On the other hand, if say you want to do a re-try on one of the API calls, then you might catch the individual exception inside a retry loop, and then re-raise the exception after the 3 (or whatever) re-attempts.
What will be the good approach to handle exception being passed between different functions ?
Ok, I’m going to be pedantic here: exceptions don’t really get “passed between functions”. Exceptions propagate up the stack. So if A calls B and B throws but doesn’t catch, then the calling point of B inside A is the next place a catch can happen. If A doesn’t catch it and nobody has wrapped A, then the program sees it and causes the error out.
I think what you’re asking is “at what level should I catch”, and that really comes back to my “what are you going to do with it when you catch it?”. General advice is catch it as close to the source as possible if you’re going to do something with it.
Say you were going to catch a KeyError
because something wasn’t in a dict and if it isn’t there you were going to add something to the dict (there are easier ways of doing this, see deafultdict
, but let’s keep the example simple). In this case, you want to wrap the point where you are accessing the dict and expecting the KeyError
.
Instead, if you’re doing a bunch of I/O operations and if any of them fail you want to close the file and error out, then you’d put all of them inside the try
. You don’t want to write the error handling code over and over.
The extreme of this goes back to my first answer to your question: if all you’re doing is printing an error instead of having the program crash, then the outer most calling point is fine.
Hope this helps.
Become a Member to join the conversation.
rjleon on April 16, 2024
Great tutorial and lots of context and practicality here. What hit home for my current project is to only use exceptions to convey a better message than what you get by default. I always wondered why I’m using a custom exception when the default messaging was already clear? I went back through my code and removed my custom exceptions.