Python: “raise exception from e” Meaning Explained!

In this article, we’ll take a look at the “raise exception from e” statement. We will learn what it means exactly and see how to use them in our programs.

We will also look at the shorter “raise” statement and learn its variations so that we can master this concept and learn where the “raise exception from e” statement fits in!

For those of you in a hurry, here is the short version of the answer.

Short Version of the Answer

The ‘raise’ statement is used to invoke or bring about exceptions in Python.

Using the raise statement

  1. you can force any exception to be raised
  2. at any point in your code
  3. with your own custom message
  4. using a single line of code
raise ValueError('invalid input')

This line of code raised an exception of the type ValueError with a message saying ‘invalid input’. This is what the output will look like:

Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    raise ValueError('invalid input')
ValueError: invalid input

There are different ways to use the raise statement, the following is a summarized version of some of them:

  1. Using just the ‘raise’ statement without any arguments
raise
Traceback (most recent call last):
 File "/home/main.py", line 1, in <module>
    raise
RuntimeError: No active exception to reraise

As you can see, it raised a RuntimeError, which is the default argument for the raise statement.

2. Reraising the same exception:

You can use the raise statement to re-raise the exception that has just been caught in the except block

num = int(input("Please enter a number: "))
try:
    print(100 / num)
except ZeroDivisionError as e:
    print("You have entered 0. This is an invalid input as we cannot divide a number by 0.")
    raise e 
Please enter a number: 0
You have entered 0. This is an invalid input as we cannot divide a number by 0.
Traceback (most recent call last):
  File "/home/main.py", line 6, in <module>
    raise e 
  File "/home/main.py", line 3, in <module>
    print(100 / num)
ZeroDivisionError: division by zero

3. Re-raising another exception:

You can also catch one type of exception and raise a different type of exception if it makes sense in your code

num = int(input("Please enter a number: "))
try:
    print(100 / num)
except ZeroDivisionError:
    raise ValueError('The entered number cannot be zero as the divisor should not be zero')
Please enter a number: 0
Traceback (most recent call last):
  File "/home/main.py", line 3, in <module>
    print(100 / num)
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/main.py", line 5, in <module>
    raise ValueError('The entered number cannot be zero as the divisor should not be zero')
ValueError: The entered number cannot be zero as the divisor should not be zero

4. Raising a custom exception:

The next level is to create a custom exception and then raising it.

A word of caution though, not all situations require the use of custom exceptions, to learn more set aside 10mins and read the article in the link below.

Python: When To Use Custom Exceptions? Explained!

class zeronum(Exception):
    pass

num = int(input("Please enter a number: "))

try:
    print(1/num)
except Exception as e:
    raise zeronum("The number cannot be 0") from e
Please enter a number: 0
Traceback (most recent call last):
  File "/home/main.py", line 7, in <module>
    print(1/num)
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/main.py", line 9, in <module>
    raise zeronum("The number cannot be 0") from e
__main__.zeronum: The number cannot be 0

That was an extremely condensed and straight-to-the-point explanation for seasoned readers who came for a quick refresh. The rest of this article is dedicated to those of you in the first steps of your journey to becoming a Python Craftsman.

By the time you reach the end of this article, I suggest you come back and read this summary once more, I assure you it will make much more sense then!

The Fundamentals

Here is a video we made about Exceptions and their place in the programming world. I suggest watching the video to get your fundamentals strong before continuing on with this article!

Now that we have a good grasp of the fundamentals, let us get back to the topic and start by learning the meaning of the raise statement.

The raise statement

I remember the time when I first came across the raise statement. Till that point I was under the impression that Exceptions are a “built-in feature” and we as programmers have no control over how and when they will occur. But then when I learned what the raise statement does, it opened up a whole new world of possibilities!

So let’s start by understanding what the raise statement does, so that we can better utilize it in our programs!

In short

raise‘ is a keyword used to force or to invoke an exception

embeddedinventor.com

Using the raise statement

  1. you can force any exception to be raised
  2. at any point in your code
  3. with your own custom message
  4. using a single line of code

For example

# this raises a ValueError
raise ValueError('invalid input')
Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    raise ValueError("invalid input")
ValueError: invalid input

The code above raised a ValueError with our custom message saying ‘invalid input’.

We can also just use the raise statement with no specific exception to invoke nor with any message just like this:

raise
Traceback (most recent call last):
  File "/home/main.py", line 1, in <module>
    raise
RuntimeError: No active exception to reraise

Using only the raise statement without any arguments leads to a RuntimeError.

The RuntimeError is raised when an error is detected that doesn’t fall in any of the other categories.

Python documentation

This ability to raise exceptions at will is extremely useful in scenarios where you need an exception to be raised to communicate to the user of your Python class/module that your module was used in an incorrect manner.

For example, lets say our python class is used to collect user information and we have a method that gets the age of the user, and the user types -32. That would be an absurd input as age cannot be negative. So we need a way to handle such situations so that the user of our class can take appropriate action.

class CollectInfor:
    def get_age():
        age = int(input("Please enter your age: "))
        if age<0:
            raise ValueError("Please enter a number greater than one. Your age cannot be less than zero! ")
        else:
            print("Thank you for entering your age!")
>>> age = CollectInfor.get_age()

Please enter your age: -32
Traceback (most recent call last):

  File "<ipython-input-3-8ee40033c622>", line 1, in <module>
    age = CollectInfor.get_age()

  File "/home/balaji/Desktop/to_delete.py", line 5, in get_age
    raise ValueError("Please enter a number greater than one. Your age cannot be less than zero! ")

ValueError: Please enter a number greater than one. Your age cannot be less than zero! 

The program is pretty simple, if your age is less than 0, an error will be popped with a custom message, here our message was ‘Please enter a number greater than one. Your age cannot be less than zero!’

The user of your class can then decide how to deal with this exception. He can either

  1. ask the user to enter it again
  2. re-raise the exception or
  3. simply let the program crash

If you wish to learn more about how to deal with exceptions, here is an excellent article for you!

Exceptions in Python: Explained for Beginners!

Alright! Now that you know what the raise keyword means, let’s look into the variations and how and when we have to use them.

How and When to Use The Variations of raise Statement

Now there are different ways to use the ‘raise’ statement, let’s look at each along with an example:

Raising an exception

The first is the one we already saw, using just the ‘raise’ statement with an exception and a message of your choice.

This one is pretty straightforward and simple:

num = int(input("Please enter an even number: "))
if num%2 != 0:
    raise ValueError("Please enter an even number. Odd number are not accepted!")
else:
    print("Your even number is", num)
Please enter an even number: 13
Traceback (most recent call last):
  File "/home/main.py", line 3, in <module>
    raise ValueError("Please enter an even number. Odd number are not accepted!")
ValueError: Please enter an even number. Odd numbers are not accepted!

Re-raising the same exception

In this method we’ll be using a try-block to catch an exception and then later reraise it. 

Have a look at what I’m talking about:

num = int(input("Please enter a number: "))
try:
    print(100 / num)
except ZeroDivisionError as e:
    print("You have entered 0. This is an invalid input as we cannot divide a number by 0.")
    raise e
Please enter a number: 0
You have entered 0. This is an invalid input as we cannot divide a number by 0.
Traceback (most recent call last):
  File "/home/main.py", line 6, in <module>
    raise e 
  File "/home/main.py", line 3, in <module>
    print(100 / num)
ZeroDivisionError: division by zero

By catching and storing the exception into an object, we’re able to use this object to print the whole exception message. If you’re wondering why we needed to do this, focus on the line ‘You have entered 0. This is an invalid input as we cannot divide a number by 0.’, this is a custom message we printed. This additional user-friendly message will help the viewer to understand what’s wrong with the code in the first place.

Another use case is to let the user of your code decide how to deal with the exception, so that you give can give some flexibility to the user.

You can also use just ‘raise’ instead of ‘raise e’:

num = int(input("Please enter a number: "))
try:
    print(100 / num)
except ZeroDivisionError as e:
    print("You have entered 0. This is an invalid input as we cannot divide a number by 0. Please run the code again and input a valid number")
    raise
Please enter a number: 0
You have entered 0. This is an invalid input as we cannot divide a number by 0. Please run the code again and input a valid number
Traceback (most recent call last):
  File "/home/main.py", line 3, in <module>
    print(100 / num)
ZeroDivisionError: division by zero

This does exactly the same thing as the code prior to this did. 

Remember, using only the ‘raise’ statement inside an except block will cause whatever exception that was caused to be raised.

Using only the ‘raise’ statement outside of the try-block will cause a RuntimeError to be raised!

If you wish to learn when to raise what exception, I suggest you read the following article

7 Most Common In-Built Exceptions in Python!

to learn how to smartly choose the correct exception for specific situations.

The re-raised exception does not have to be of the same type, we can also catch exception of type A and re-raise type B if the situation demands it. Let see how we can do that next!

Re-raising another exception (raise Exception from e)

Finally we are ready to learn about the topic of this article which is “raise Exception from e”!

In the next example, lets raise a ValueError upon catching a ZeroDivisionError:

num = int(input("Please enter a number: "))
try:
    print(100 / num)
except ZeroDivisionError:
    raise ValueError('The entered number cannot be zero as the divisor should not be zero')
Please enter a number: 0
Traceback (most recent call last):
  File "/home/main.py", line 3, in <module>
    print(100 / num)
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/main.py", line 5, in <module>
    raise ValueError('The entered number cannot be zero as the divisor should not be zero')
ValueError: The entered number cannot be zero as the divisor should not be zero

The syntax for this is:

raise ExceptionType from Cause

The word “from” simply indicates the source of the exception. 

In this case, the source is the variable “e”. “e” is a common abbreviation for “exception”, and it’s often used to represent the exception object in a try-except block. In other words, ‘e’ is the cause. Since ‘e’ is a variable/object, you can name it however you wish!

This is handy in specific situations. For example, what we did right now is we raised a ValueError after ZeroDivisionError was raised providing more context to the problem!

Raising a custom exception

We can also create our own custom exception if we want to have a “tailored” exception to some problem in our code.

Lets take a look at an example.

class zeronum(Exception):
    pass

num = int(input("Please enter a number: "))

try:
    print(1/num)
except Exception as e:
    raise zeronum("The number cannot be 0") from e

Here we have created a simple custom exception (by making a class that inherits the Exception class) and followed the exact same procedure that we did for the previous one just now.

And then we “raise”d that custom exception when our code didn’t work, just like we would with any built-in exceptions.

Please enter a number: 0
Traceback (most recent call last):
  File "/home/main.py", line 7, in <module>
    print(1/num)
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/main.py", line 9, in <module>
    raise zeronum("The number cannot be 0") from e
__main__.zeronum: The number cannot be 0

A word of caution though, not all situations require the use of custom exceptions, to learn more set aside 10mins and read the article in the link below.

Python: When To Use Custom Exceptions? Explained!

where you can learn when to use custom and when to use builtin exceptions.

Also we have another article which is closely related to this one which you can find in the link below.

Python: Manually throw/raise an Exception using the “raise” statement

where I have explained more details such as

  • best practices when using raise statement
  • How to avoid hiding bugs with the help of raise statement

I suggest add that one to your reading list!

Now that we have learnt the various ways of raising exceptions, the next logical step is to have a look at the other side of the coin and learn how to debug exceptions raised by others like a professional. To continue your learning I invite you to checkout out our video on that topic!

And with that, I will end this article.

Congratulations for making it to the end of the article, not many have the perseverance to do so!

I hope you enjoyed reading this article and found it useful!

Feel free to share it with your friends and colleagues!

If your thirst for knowledge has not been quenched yet, here are some related articles that might spark your interest!

Related Articles

Custom Exception In Python: Everything You Need To Know!

7 Most Common In-Built Exceptions in Python!

Exceptions in Python: Explained for Beginners!

Thanks to Namazi Jamal for his contributions to writing this article!

Photo of author
Editor
Balaji Gunasekaran
Balaji Gunasekaran is a Senior Software Engineer with a Master of Science degree in Mechatronics and a bachelor’s degree in Electrical and Electronics Engineering. He loves to write about tech and has written more than 300 articles. He has also published the book “Cracking the Embedded Software Engineering Interview”. You can follow him on LinkedIn