Close
Close

Python Raising Exceptions


Normally, exceptions are thrown when there is some problem in the code. In Python, we can also manually raise an exception.

But why would we raise an exception on our own?

Consider a scenario where we are asking the user to enter their roll number as input. We know that a roll number can only be a positive number. So, if the user enters a non-positive value as their roll number, we might want to throw an exception.

There can be more such cases where the values entered by the user or some piece of code are considered invalid for our program. In those cases, we can manually raise an exception.

Seems interesting, right? Let’s write a program which throws an error if the user enters a non-positive roll number.

Python Raising an Exception


try:
    roll = int(input("Please enter your roll number"))
    if roll <= 0:
        raise ValueError()

except ValueError:
    print("ValueError Exception thrown")

print("Outside of try-except clauses.")
Output
Please enter your roll number -5
ValueError Exception thrown
Outside of try-except clauses.

Inside the try clause, we are taking the input from the user. Then we are checking if the number entered by the user is non-positive. If it is, then we are manually raising the ValueError exception by writing raise ValueError(). We are also handling this exception using an except clause.

Note that in the above example, we have raised an exception of type ValueError. However, we can raise any other type of exception as well if the entered value is not positive. We chose to raise ValueError because normally ValueError exceptions are raised when some value is incorrect. So, it is advisable to choose the exception type that best matches the reason you are raising it.

Similarly, an IndexError exception can be raised using raise IndexError().

We can also define our raised exception by passing values to the exception while raising it. Let’s define the ValueError exception we raised in the previous example.

try:
    roll = int(input("Please enter your roll number"))
    if roll <= 0:
        raise ValueError("The number entered is not positive")

except ValueError as v:
    print("ValueError Exception thrown")
    print(v)

print("Outside of try-except clauses.")
Output
Please enter your roll number -5
ValueError Exception thrown
The number entered is not positive
Outside of try-except clauses.

In this example, while raising the ValueError exception, we passed a string "The number entered is not positive" to it. This passed value works as the definition of the raised exception. Therefore, on printing the ValueError (in the form of v) inside the except clause, this definition of the exception (the string value passed while raising the exception) got printed.

We can raise any number of exceptions from a try clause.

Let’s take another example. Suppose we are hosting a webinar in which only the students of the age group of 5 to 20 years are allowed. If any student who is not in this age group tries to register, then we will throw an exception.

try:
    age = int(input("Please enter your age"))
    if age < 5:
        raise ValueError("Not allowed! Your age is less than 5")

    if age > 20:
        raise ValueError("Not allowed! Your age is greater than 20")

except ValueError as v:
    print("ValueError Exception thrown")
    print(v)
Output
Please enter your age 26
ValueError Exception thrown
Not allowed! Your age is greater than 20

In this example, we are asking the user to enter the age. If the entered age is less than 5, then we are throwing a ValueError exception with a definition, and if the age is greater than 20, then we are throwing another ValueError exception with another definition. You can run this program and check the result for different inputs.

Look at another example.

try:
    roll = int(input("Please enter your roll number"))
    if roll <= 0:
        raise ValueError("The number entered is not positive")
    print(num)

except ValueError as v:
    print("ValueError Exception thrown")
    print(v)

except:
    print("Some error occurred")

print("Outside of try-except clauses.")
Output
Please enter your roll number 5
Some error occurred
Outside of try-except clauses.

Here we are forcefully throwing a ValueError exception if the entered number is not positive. We are handling the ValueError exceptions by the first except clause. All other types of exceptions are handled by the second generic except block. In this example, we gave 5 as input and so no ValueError exception was raised, but the statement print(num) threw a NameError exception because the variable num is not defined. This exception was handled by the second except clause.

While raising an exception, if we are not sure about which type of exception we should raise, then we can raise a generic exception Exception as shown below.

try:
    roll = int(input("Please enter your roll number"))
    if roll <= 0:
        raise Exception("The number entered is not positive")

except Exception as e:
    print(e)

print("Outside of try-except clauses.")
Output
Please enter your roll number -5
The number entered is not positive
Outside of try-except clauses.

You must have understood this example. We are raising a generic Exception when the entered value is not positive.

Till now, we have been raising either a generic Exception or specific built-in exceptions  like NameError, ValueError, etc in Python. We can also create our own exceptions.

Python Defining Our Own Exceptions


Before learning to create new exceptions, let’s see what exception classes are.

All exceptions we studied till now are built-in classes in Python. Thus, IndexError, TypeError and all the other exceptions are built-in classes. 

We also know that all classes are subclasses of the object class. The object class is a built-in class in Python. Similarly, all the exception classes are direct or indirect subclasses of the built-in Exception class. Thus, exceptions like IndexError, TypeError, ValueError, etc are subclasses of the Exception class. Also, the Exception class itself is a subclass of the object class. Let’s prove this.

print(issubclass(ValueError, Exception))
print(issubclass(Exception, object))
Output
True
True

From this example, we can see that ValueError is a subclass of Exception and Exception is a subclass of the object class.

Now, let’s create our own exception.

# defining a new exception named MyCustomError
class MyCustomError(Exception):
    pass

# raising the error
raise MyCustomError
Output
Traceback (most recent call last):
  File "script.py", line 6, in <module>
    raise MyCustomError __main__.MyCustomError

We created a new exception named MyCustomError which inherits the Exception class and raised this exception using the raise keyword by writing raise MyCustomError. 

Look at another example.

# defining a new exception named MyCustomError
class MyCustomError(Exception):
    pass

roll = int(input("Please enter your roll number"))
if roll <= 0:
    raise MyCustomError("The number entered is not positive")
Output
Please enter your roll number -5
Traceback (most recent call last):
  File "script.py", line 7, in <module>
    raise MyCustomError("The number entered is not positive")
__main__.MyCustomError: The number entered is not positive

Here if the user enters a non-positive value, we are raising our exception by passing the value "The number entered is not positive" to it which serves as its description. You can see that the error message we get when the exception is raised is quite similar to the one we get when some built-in exception is thrown.

If we want to create multiple custom exception classes, then it is a good practice to create a custom base exception class and inherit all the other exception classes from this base class. It is also a good practice to keep minimal code inside the exception classes. 

class Error(Exception):
    """Base class for all exceptions"""
    pass

class PasswordSmallError(Error):
    """Raised when the input password is small"""
    pass

class PasswordLargeError(Error):
    """Raised when the input password is large"""
    pass

class PasswordInvalidError(Error):
    """Raised when the input password is invalid"""
    pass

We created a base exception class named Error. All the other exception classes are created as its subclass.

Now let’s see an example in which we will ask the user to enter a password. If the password entered by the user is too short or too long, then we will throw exceptions.

# defining exceptions

class Error(Exception):
    """Base class for all exceptions"""
    pass

class PasswordSmallError(Error):
    """Raised when the input password is small"""
    pass

class PasswordLargeError(Error):
    """Raised when the input password is large"""
    pass

try:
    password = input("Enter a password")

    if len(password) < 6:
        raise PasswordSmallError("Password is short!")

    if len(password) > 15:
        raise PasswordLargeError("Password is long!")
	
except PasswordSmallError as ps:
    print(ps)

except PasswordLargeError as pl:
    print(pl)
Output
Enter a password abcd
Password is short!

You must have understood the code. We are asking the user to enter a password, and raising the PasswordSmallError exception if the password length is less than 6 characters and the PasswordLargeError exception if its length is more than 15 characters. We are also handing both the exceptions in different except clauses.

To learn from simple videos, you can always look at our Python video course on CodesDope Pro. It has over 500 practice questions and over 20 projects.
The only failure is not to try.
- George Clooney


Ask Yours
Post Yours
Doubt? Ask question