Raising and Handling Exceptions
A custom exception is a user-defined class that inherits from Exception and represents an error specific to an application's domain.
Try it: try / except / else / finally
How an exception jumps out of a try block to the first matching except clause, when else runs, and why finally always runs.
How it works
- Statements in try run until one raises an exception; the rest of try is skipped.
- Python checks the except clauses in order and runs the first one whose type matches.
- If nothing was raised, the else block runs instead.
- finally runs in every case.
Default run (9 steps): Call safe_divide('4'). … Return 25.0. Output was: Worked: 25.0 / Done.
Simplified: One fixed function; int() and / are modelled exactly (including how Python prints floats), but nothing is executed as Python.
Loading the simulation…
Why Generic Errors Are Not Always Enough
Python provides built-in exceptions such as ValueError and TypeError for common problems. However, an application often has conditions that are specific to its own rules. A text-input validator, for example, may need to represent the condition that an input is too short. A custom exception gives that condition a clear name instead of forcing it into a generic error category.
A custom exception is a user-defined class that inherits from Exception and represents an error specific to an application's domain.
Defining the Exception Class
Define a custom exception by creating a class whose superclass is Exception. The class name describes the application condition that the exception represents. A minimal class can contain pass, meaning that it adds no methods or attributes beyond what it inherits from Exception.
The inheritance chain from BaseException through Exception to ShortInputException makes the custom exception compatible with Python's exception-handling system. It can be handled by an except block that catches the custom type, Exception, or BaseException.
Storing Useful Error Details
A custom exception becomes more useful when it carries information about the problem. Add an __init__ method to store relevant details as instance attributes. In the ShortInputException example, the exception stores the actual input length and the minimum length required.
The __init__ method receives length and atleast as arguments. It calls Exception.__init__(self) to initialize the parent Exception class, then stores the two values as instance attributes. Code that catches the exception can later read those attributes and respond to the exact error details.
Store details that help the handler explain what went wrong or make a decision based on the specific error.
Following Control After raise
Use the raise statement to create and throw an exception. The exception class name follows raise, along with the arguments required by its __init__ method. When the raise statement executes, normal execution stops at that point. Control immediately moves to the nearest enclosing try-except block that can handle the exception type.
class ShortInputException(Exception):
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
text = "hi"
try:
if len(text) < 3:
raise ShortInputException(len(text), 3)
except ShortInputException as error:
print(error.length)
print(error.atleast)- 1The program defines
ShortInputExceptionas a subclass of Exception. - 2The try block tests the input condition.
- 3Because the input is shorter than the required minimum, the raise statement executes.
- 4Execution does not continue after raise inside the try block.
- 5The matching except block catches
ShortInputException. - 6The handler reads the data stored on the exception object.
- The class defines the custom exception and the data it stores.
- The input has length 2.
- The condition is true because the input is shorter than 3 characters.
- raise creates a
ShortInputExceptionwith the actual length and required minimum. - as error binds the caught exception object to the name error.
- The handler can access the stored length and atleast attributes.
2
3Handling the Domain Condition
Validating a Minimum Input Length
Represent an input shorter than three characters with a custom exception and handle the stored details.
- 1Define the exception
Create
ShortInputExceptionas a subclass of Exception. Give it an__init__method that stores the actual length and required minimum. - 2Check the input
Inside a try block, compare the input length with the minimum of 3.
- 3Raise the custom type
If the length is too short, raise
ShortInputExceptionand pass the actual length and 3 as arguments. - 4Handle the condition
Catch
ShortInputExceptionwith as and use the exception object's length and atleast attributes to provide specific feedback. - 5Handle successful input
If the input has at least 3 characters, the error is not raised and the else path can confirm successful input.
The program distinguishes the domain-specific condition of input being too short from other possible errors and gives the handler the exact values it needs.
Input acceptedWith the input set to hello, the length is at least 3, so the raise statement does not execute. The except block is skipped and the else block confirms successful input. If the input contained fewer than 3 characters, the custom exception would be raised and the handler would use its stored length and atleast values.
Mistakes with Custom Exceptions
Common mistake Defining the custom class without inheriting from Exception
What it looks likeclass ShortInputException: passWhy it failsThe custom class is not connected to Exception through the inheritance chain described for Python exception handling.
Do this insteadDefine it as class ShortInputException(Exception):Common mistake Raising the exception without the arguments required by __init__
What it looks likeraise ShortInputException()Why it failsThe example exception's
__init__method expects the actual length and the minimum length.Do this insteadPass both values, such as raise ShortInputException(len(text), 3).
Common mistake Catching the exception but ignoring its stored details
What it looks likeexcept ShortInputException: print("Invalid input")Why it failsThe handler misses the length and atleast attributes that can make the feedback more specific.
Do this insteadBind the object with as and access its attributes, such as except ShortInputException as error.
Common mistake Expecting execution to continue after raise inside the try block
Why it failsWhen raise executes, control immediately moves to the nearest enclosing try-except block that can handle the exception.
Do this insteadPlace handling logic in the matching except block.
Practice and Recall
What do you think happens?
In the input-validation example, what happens when text is set to "hi" and the minimum is 3?
Reveal answer
ShortInputException is raised and the except block handles it.
The input length is less than the required minimum. The raise statement creates the custom exception with the actual length and minimum, and control moves to the matching except block.
Design a custom exception for a domain-specific condition in a program. Give the class a name that describes the condition, decide whether the handler needs stored details, and identify the arguments that the raise statement should provide.
Hints
- Begin with a class that inherits from Exception.
- If the handler needs details, store them as instance attributes in
__init__. - Make the arguments supplied to raise match the parameters expected by
__init__. - Catch the custom type with an except block and use as to access the exception object.
Key Takeaways
- 1A custom exception is a user-defined class that inherits from Exception.
- 2A minimal custom exception can use pass, while an
__init__method can store useful error details. - 3The raise statement creates the custom exception and passes arguments to its
__init__method. - 4When raise executes, control moves to the nearest matching try-except handler.
- 5Custom exceptions make domain-specific error conditions clearer and allow handlers to provide targeted responses.
At a glance
- Custom exceptions represent application-specific error conditions.
- They inherit from Exception and therefore fit into Python's exception-handling hierarchy.
- An
__init__method can store details such as the actual input length and required minimum. - raise transfers control to a matching except block, where the handler can access the exception object's data.