Python raise error with message

Prerequisite This article is an extension to Exception Handling. In this article we will try to cover How to Define Custom Exceptions in Python with Examples. Example class CustomError Exception pass raise CustomError Example of Custom Exceptions in Python Output CustomError Example of Custom Exceptions in Python Python throws errors and exceptions

Prerequisite: This article is an extension to Exception Handling.

In this article, we will try to cover How to Define Custom Exceptions in Python with Examples. 

Example: 

class CustomError(Exception):
    pass

raise CustomError("Example of Custom Exceptions in Python")

Output: CustomError: Example of Custom Exceptions in Python

Python throws errors and exceptions when the code goes wrong, which may cause the program to stop abruptly. Python also provides an exception handling method with the help of try-except. Some of the standard exceptions which are most frequent include IndexError, ImportError, IOError, ZeroDivisionError, TypeError, and FileNotFoundError.

User-Defined Exception in Python

Exceptions need to be derived from the Exception class, either directly or indirectly. Although not mandatory, most of the exceptions are named as names that end in “Error” similar to the naming of the standard exceptions in python. For example,

Python3

class MyError(Exception):

    def __init__(self, value):

        self.value = value

    def __str__(self):

        return(repr(self.value))

try:

    raise(MyError(3*2))

except MyError as error:

    print('A New Exception occurred: ', error.value)

Output

('A New Exception occurred: ', 6)

Customizing Exception Classes

To know more about class Exception, run the code below 

Python3

Output

Help on class Exception in module exceptions:

class Exception(BaseException)
 |  Common base class for all non-exit exceptions.
 |  
 |  Method resolution order:
 |      Exception
 |      BaseException
 |      __builtin__.object
 |  
 |  Methods defined here:
 |  
 |  __init__(...)
 |      x.__init__(...) initializes x; see help(type(x)) for signature
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __new__ = <built-in method __new__ of type object>
 |      T.__new__(S, ...) -> a new object with type S, a subtype of T
 |  
 |  ----------------------------------------------------------------------
 |  Methods inherited from BaseException:
 |  
 |  __delattr__(...)
 |      x.__delattr__('name') <==> del x.name
 |  
 |  __getattribute__(...)
 |      x.__getattribute__('name') <==> x.name
 |  
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |  
 |  __getslice__(...)
 |      x.__getslice__(i, j) <==> x[i:j]
 |      
 |      Use of negative indices is not supported.
 |  
 |  __reduce__(...)
 |  
 |  __repr__(...)
 |      x.__repr__() <==> repr(x)
 |  
 |  __setattr__(...)
 |      x.__setattr__('name', value) <==> x.name = value
 |  
 |  __setstate__(...)
 |  
 |  __str__(...)
 |      x.__str__() <==> str(x)
 |  
 |  __unicode__(...)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from BaseException:
 |  
 |  __dict__
 |  
 |  args
 |  
 |  message

Example 1: User-Defined class with Multiple Inheritance

In the below article, we have created a class named “Error” derived from the class Exception. This base class is inherited by various user-defined classes to handle different types of python raise an exception with message

Python3

class Error(Exception):

    pass

class zerodivision(Error):

    pass

try:

    i_num = int(input("Enter a number: "))

    if i_num == 0:

        raise zerodivision

except zerodivision:

    print("Input value is zero, try again!")

    print()

Output

Enter a number: Input value is zero, try again!
()
Enter a number: Input value is zero, try again!

Example 2: Deriving Error from Super Class Exception

Superclass Exceptions are created when a module needs to handle several distinct errors. One of the common ways of doing this is to create a base class for exceptions defined by that module. Further, various subclasses are defined to create specific exception classes for different error conditions.

Python3

class Error(Exception):

    pass

class TransitionError(Error):

    def __init__(self, prev, nex, msg):

        self.prev = prev

        self.next = nex

        self.msg = msg

try:

    raise(TransitionError(2, 3*2, "Not Allowed"))

except TransitionError as error:

    print('Exception occurred: ', error.msg)

Output

('Exception occurred: ', 'Not Allowed')

How to use standard Exceptions as a base class?

A runtime error is a class that is a standard exception that is raised when a generated error does not fall into any category. This program illustrates how to use runtime error as a base class and network error as a derived class. In a similar way, an exception can be derived from the standard exceptions of Python.

Python3

class Networkerror(RuntimeError):

    def __init__(self, arg):

        self.args = arg

try:

    raise Networkerror("Error")

except Networkerror as e:

    print(e.args)

Output

('E', 'r', 'r', 'o', 'r')

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Raising and Handling Python Exceptions

A Python program terminates as soon as it encounters an error. In Python, an error can be a syntax error or an exception. In this article, you will see what an exception is and how it differs from a syntax error. After that, you will learn about raising exceptions and making assertions. Then, you’ll finish with a demonstration of the try and except block.

An introduction to exceptions in Python

Exceptions versus Syntax Errors

Syntax errors occur when the parser detects an incorrect statement. Observe the following example:

>>> print( 0 / 0 ))
  File "<stdin>", line 1
    print( 0 / 0 ))
                  ^
SyntaxError: invalid syntax

The arrow indicates where the parser ran into the syntax error. In this example, there was one bracket too many. Remove it and run your code again:

>>> print( 0 / 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

This time, you ran into an exception error. This type of error occurs whenever syntactically correct Python code results in an error. The last line of the message indicated what type of exception error you ran into.

Instead of showing the message exception error, Python details what type of exception error was encountered. In this case, it was a ZeroDivisionError. Python comes with various built-in exceptions as well as the possibility to create self-defined exceptions.

Raising an Exception

We can use raise to throw an exception if a condition occurs. The statement can be complemented with a custom exception.

Illustration of  raise statement usage

If you want to throw an error when a certain condition occurs using raise, you could go about it like this:

x = 10
if x > 5:
    raise Exception('x should not exceed 5. The value of x was: {}'.format(x))

When you run this code, the output will be the following:

Traceback (most recent call last):
  File "<input>", line 4, in <module>
Exception: x should not exceed 5. The value of x was: 10

The program comes to a halt and displays our exception to screen, offering clues about what went wrong.

The AssertionError Exception

Instead of waiting for a program to crash midway, you can also start by making an assertion in Python. We assert that a certain condition is met. If this condition turns out to be True, then that is excellent! The program can continue. If the condition turns out to be False, you can have the program throw an AssertionError exception.

Python assert statement

Have a look at the following example, where it is asserted that the code will be executed on a Linux system:

import sys
assert ('linux' in sys.platform), "This code runs on Linux only."

If you run this code on a Linux machine, the assertion passes. If you were to run this code on a Windows machine, the outcome of the assertion would be False and the result would be the following:

Traceback (most recent call last):
  File "<input>", line 2, in <module>
AssertionError: This code runs on Linux only.

In this example, throwing an AssertionError exception is the last thing that the program will do. The program will come to halt and will not continue. What if that is not what you want?

The try and except Block: Handling Exceptions

The try and except block in Python is used to catch and handle exceptions. Python executes code following the try statement as a “normal” part of the program. The code that follows the except statement is the program’s response to any exceptions in the preceding try clause.

Diagram showing try and except statements

As you saw earlier, when syntactically correct code runs into an error, Python will throw an exception error. This exception error will crash the program if it is unhandled. The except clause determines how your program responds to exceptions.

The following function can help you understand the try and except block:

def linux_interaction():
    assert ('linux' in sys.platform), "Function can only run on Linux systems."
    print('Doing something.')

The linux_interaction() can only run on a Linux system. The assert in this function will throw an AssertionError exception if you call it on an operating system other then Linux.

You can give the function a try using the following code:

try:
    linux_interaction()
except:
    pass

The way you handled the error here is by handing out a pass. If you were to run this code on a Windows machine, you would get the following output:

You got nothing. The good thing here is that the program did not crash. But it would be nice to see if some type of exception occurred whenever you ran your code. To this end, you can change the pass into something that would generate an informative message, like so:

try:
    linux_interaction()
except:
    print('Linux function was not executed')

Execute this code on a Windows machine:

Linux function was not executed

When an exception occurs in a program running this function, the program will continue as well as inform you about the fact that the function call was not successful.

What you did not get to see was the type of error that was thrown as a result of the function call. In order to see exactly what went wrong, you would need to catch the error that the function threw.

The following code is an example where you capture the AssertionError and output that message to screen:

try:
    linux_interaction()
except AssertionError as error:
    print(error)
    print('The linux_interaction() function was not executed')

Running this function on a Windows machine outputs the following:

Function can only run on Linux systems.
The linux_interaction() function was not executed

The first message is the AssertionError, informing you that the function can only be executed on a Linux machine. The second message tells you which function was not executed.

In the previous example, you called a function that you wrote yourself. When you executed the function, you caught the AssertionError exception and printed it to screen.

Here’s another example where you open a file and use a built-in exception:

try:
    with open('file.log') as file:
        read_data = file.read()
except:
    print('Could not open file.log')

If file.log does not exist, this block of code will output the following:

This is an informative message, and our program will still continue to run. In the Python docs, you can see that there are a lot of built-in exceptions that you can use here. One exception described on that page is the following:

Exception FileNotFoundError

Raised when a file or directory is requested but doesn’t exist. Corresponds to errno ENOENT.

To catch this type of exception and print it to screen, you could use the following code:

try:
    with open('file.log') as file:
        read_data = file.read()
except FileNotFoundError as fnf_error:
    print(fnf_error)

In this case, if file.log does not exist, the output will be the following:

[Errno 2] No such file or directory: 'file.log'

You can have more than one function call in your try clause and anticipate catching various exceptions. A thing to note here is that the code in the try clause will stop as soon as an exception is encountered.

Look at the following code. Here, you first call the linux_interaction() function and then try to open a file:

try:
    linux_interaction()
    with open('file.log') as file:
        read_data = file.read()
except FileNotFoundError as fnf_error:
    print(fnf_error)
except AssertionError as error:
    print(error)
    print('Linux linux_interaction() function was not executed')

If the file does not exist, running this code on a Windows machine will output the following:

Function can only run on Linux systems.
Linux linux_interaction() function was not executed

Inside the try clause, you ran into an exception immediately and did not get to the part where you attempt to open file.log. Now look at what happens when you run the code on a Linux machine:

[Errno 2] No such file or directory: 'file.log'

Here are the key takeaways:

  • A try clause is executed up until the point where the first exception is encountered.
  • Inside the except clause, or the exception handler, you determine how the program responds to the exception.
  • You can anticipate multiple exceptions and differentiate how the program should respond to them.
  • Avoid using bare except clauses.

The else Clause

In Python, using the else statement, you can instruct a program to execute a certain block of code only in the absence of exceptions.

Diagram of try, except, and else statements in Python

Look at the following example:

try:
    linux_interaction()
except AssertionError as error:
    print(error)
else:
    print('Executing the else clause.')

If you were to run this code on a Linux system, the output would be the following:

Doing something.
Executing the else clause.

Because the program did not run into any exceptions, the else clause was executed.

You can also try to run code inside the else clause and catch possible exceptions there as well:

try:
    linux_interaction()
except AssertionError as error:
    print(error)
else:
    try:
        with open('file.log') as file:
            read_data = file.read()
    except FileNotFoundError as fnf_error:
        print(fnf_error)

If you were to execute this code on a Linux machine, you would get the following result:

Doing something.
[Errno 2] No such file or directory: 'file.log'

From the output, you can see that the linux_interaction() function ran. Because no exceptions were encountered, an attempt to open file.log was made. That file did not exist, and instead of opening the file, you caught the FileNotFoundError exception.

Cleaning Up After Using finally

Imagine that you always had to implement some sort of action to clean up after executing your code. Python enables you to do so using the finally clause.

Diagram explaining try except else finally statements

Have a look at the following example:

try:
    linux_interaction()
except AssertionError as error:
    print(error)
else:
    try:
        with open('file.log') as file:
            read_data = file.read()
    except FileNotFoundError as fnf_error:
        print(fnf_error)
finally:
    print('Cleaning up, irrespective of any exceptions.')

In the previous code, everything in the finally clause will be executed. It does not matter if you encounter an exception somewhere in the try or else clauses. Running the previous code on a Windows machine would output the following:

Function can only run on Linux systems.
Cleaning up, irrespective of any exceptions.

Summing Up

After seeing the difference between syntax errors and exceptions, you learned about various ways to raise, catch, and handle exceptions in Python. In this article, you saw the following options:

  • raise allows you to throw an exception at any time.
  • assert enables you to verify if a certain condition is met and throw an exception if it isn’t.
  • In the try clause, all statements are executed until an exception is encountered.
  • except is used to catch and handle the exception(s) that are encountered in the try clause.
  • else lets you code sections that should run only when no exceptions are encountered in the try clause.
  • finally enables you to execute sections of code that should always run, with or without any previously encountered exceptions.

Hopefully, this article helped you understand the basic tools that Python has to offer when dealing with exceptions.

Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Raising and Handling Python Exceptions

An Exception is raised whenever there is an error encountered, and it signifies that something went wrong with the program. By default, there are many exceptions that the language defines for us, such as TypeError when the wrong type is passed. In this article, we shall look at how we can create our own Custom Exceptions in Python.

But before we take a look at how custom exceptions are implemented, let us find out how we could raise different types of exceptions in Python.


Raise Exceptions

Python allows the programmer to raise an Exception manually using the raise keyword.

Format: raise ExceptionName

The below function raises different exceptions depending on the input passed to the function.

def exception_raiser(string):
    if isinstance(string, int):
        raise ValueError
    elif isinstance(string, str):
        raise IndexError
    else:
        raise TypeError

Output:

>>> exception_raiser(123)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in exception_raiser
ValueError
>>> exception_raiser('abc')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in exception_raiser
IndexError
>>> exception_raiser([123, 456])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in exception_raiser
TypeError

As you can observe, different types of Exceptions are raised based on the input, at the programmer’s choice. This allows for good flexibility of Error Handling as well, since we can actively predict why an Exception can be raised.


Defining Custom Exceptions

Similarly, Python also allows us to define our own custom Exceptions. We are in complete control of what this Exception can do, and when it can be raised, using the raise keyword. Let us look at how we can define and implement some custom Exceptions.

1. Create a Custom Exception Class

We can create a custom Exception class to define the new Exception. Again, the idea behind using a Class is because Python treats everything as a Class. So it doesn’t seem that outlandish that an Exception can be a class as well!

All Exceptions inherit the parent Exception Class, which we shall also inherit when creating our class.

We shall create a Class called MyException, which raises an Exception only if the input passed to it is a list and the number of elements in the list is odd.

class MyException(Exception):
	pass

def list_check(lst):
    if len(lst) % 2 != 0:
        raise MyException

# MyException will not be raised
list_check([1, 2, 3, 4])

# MyException will be raised
list_check([1, 3, 5])    

Output:

[email protected]:~# python3 exceptions.py
Traceback (most recent call last):
  File "exceptions.py", line 12, in <module>
    list_check([1, 3, 5])
  File "exceptions.py", line 6, in list_check
    raise MyException
__main__.MyException

2. Add a custom Message and Error

We can add our own error messages and print them to the console for our Custom Exception. This involves passing two other parameters in our MyException class, the message and error parameters.

Let us modify our original code to account for a custom Message and Error for our Exception.

class MyException(Exception):
    def __init__(self, message, errors):
        # Call Exception.__init__(message)
        # to use the same Message header as the parent class
        super().__init__(message)
        self.errors = errors
        # Display the errors
        print('Printing Errors:')
        print(errors)

def list_check(lst):
    if len(lst) % 2 != 0:
        raise MyException('Custom Message', 'Custom Error')

# MyException will not be raised
list_check([1, 2, 3, 4])

# MyException will be raised
list_check([1, 3, 5])

Output:

Printing Errors:
Custom Error
Traceback (most recent call last):
  File "exceptions.py", line 17, in <module>
    list_check([1, 3, 5])
  File "exceptions.py", line 11, in list_check
    raise MyException('Custom Message', 'Custom Error')
__main__.MyException: Custom Message

We have thus successfully implemented our own Custom Exceptions, including adding custom error messages for debugging purposes! This can be very useful if you are building a Library/API and another programmer wants to know what exactly went wrong when the custom Exception is raised.


Conclusion

In this article, we learned how to raise Exceptions using the raise keyword, and also build our own Exceptions using a Class and add error messages to our Exception.

References

  • JournalDev article on Custom Exceptions
  • Exception Handling in Python

  1. Create a Custom Exception Class in Python
  2. Execute Exception-Handling Using the try...except Block in Python

Create Custom Exceptions in Python

This tutorial will demonstrate you can create custom exception classes in Python. Here, we’ll show how you can properly perform exception handling, define custom exception classes, and override existing built-in exceptions.

Exceptions are a type of event that occurs whenever something within a program doesn’t go as intended or disrupts the flow of the intended use-case of the program. Without exception handling, the program will cease to execute entirely, and the exception would have to either be fixed or handled.

Create a Custom Exception Class in Python

Creating an Exception Class in Python is done the same way as a regular class. The main difference is you have to include the Python’s base Exception class to inform the compiler that the class you’re making is an exception class.

Let’s test this method out to create an exception class called DemoException and use the placeholder control flow keyword pass inside as a placeholder.

class DemoException(Exception):
    pass

Execute Exception-Raising Using the Keyword raise in Python

To test the DemoException class and see what it displays when it’s actually triggered, perform exception raising. Exception-raising is synonymous with exception-throwing in other programming languages.

Using the keyword raise, trigger an exception using the given exception class and outputs an exception message.

class DemoException(Exception):
    pass

raise DemoException

Output:

Traceback (most recent call last):
  File "/Users/demo/python/demo_exception.py", line 4, in <module>
    raise DemoException
__main__.DemoException

A standard exception will look like in the terminal if no custom exception message has been declared.

Declare a Custom Exception Message in Python

To declare a custom exception message for DemoException, override the __init__() method of the exception class and include the message that should be outputted for the exception in the parameters, along with the mandatory self-referential parameter self.

For example, let’s override the __init__() method and create a custom message for the DemoException class:

class DemoException(Exception):
    def __init__(self, message):
        super().__init__(message)

Take note that for the message to be integrated into your exception successfully, call the base Exception class, __init__() method, and include the message as an argument.

Let’s call the exception class again using the raise keyword, and now, passing a custom message with it:

class DemoException(Exception):
    def __init__(self, message):
        super().__init__(message)
        
message = "Exception Triggered! Something went wrong."
raise DemoException(message)

The output should look like this:

Traceback (most recent call last):
  File "/Users/demo/python/helloworld.py", line 6, in <module>
    raise DemoException(message)
__main__.DemoException: Exception Triggered! Something went wrong.

We’ve now successfully created and triggered an exception class with a custom error message.

For actual situations that may trigger an exception, how do we handle and raise these exceptions? You can solve this problem neatly by implementing exception-handling using the try...except block.

Execute Exception-Handling Using the try...except Block in Python

The try...except block is much like the try-catch block in other languages like Java.

The try...except block has 2 main blocks and 2 optional blocks:

  • try (required) — The main block responsible for encapsulating the code block where the exception might be triggered. The try block halts the whole process within it whenever an exception is triggered.
  • except (required) — The block program proceeds whenever a specified exception is triggered. This block typically contains a descriptive error message for the caller or just a simple print() statement. There may be more than one except block in a single try block, each one catching different exceptions.
  • else (optional) — This optional block is where the program will proceed if the try block did not trigger any exceptions.
  • finally (optional) — This optional block runs once everything from the previous 3 blocks has been performed regardless if an exception is triggered or not.

Let’s use the previous example using the DemoException class to try a simple try...except block.

First, wrap the raise keyword in a function and put it inside the try...except block.

The function that we’ll create for this example is a function that accepts a number and throws an exception if it sends 0. If it sends any other number, then the code will proceed as intended. Check the example below:

class DemoException(Exception):
    def __init__(self, message):
        super().__init__(message)
        

message = "Exception Triggered! Something went wrong."

def triggerException(num):
    if (num == 0):
        raise DemoException(message)
    else:
        print(num)


try:
    triggerException(0)
    print("Code has successfully been executed.")
except DemoException:
    print("Error: Number should not be 0.")

Since the triggerException() passed 0 as an argument, the code should trigger DemoException. Here we should expect the raise keyword message to be overridden with whatever is inside the except block as the output.

Notice that the print() line after the triggerException() function call was not outputted. It’s because the function raised an exception; therefore, it immediately halted all the processes within the try block and proceeded directly to the except block.

Output:

Error: Number should not be 0.

Now, let’s try passing a valid number like 20, for example.

try:
    triggerException(20)
    print("Code has successfully been executed.")
except DemoException:
    print("Error: Number should not be 0.")

Output:

20
Code has successfully been executed.

Let’s try chaining the except blocks and create another exception. Let’s call the new exception NumberFormatException, which triggers if the given input is not a number. For this exception class, let’s declare the message inside the class.

class NumberFormatException(Exception, value):
    message = f'{value} is not a number'
    def __init__(self):
        super().__init__(message)

Now, modify the code above to handle the new exception class NumberFormatException:

class DemoException(Exception):
    def __init__(self, message):
        super().__init__(message)
        
class NumberFormatException(Exception):
    def __init__(self, message, value):
        message = f'{value} is not a number'
        super().__init__(message)
        
message = "Exception occured."

def triggerException(num):
    if (not num.isdigit()):
        raise NumberFormatException(message, num)
    elif (num == 0):
        raise DemoException(message)
    else:
        print(num)

num = "sample string"
try:
    triggerException(num)
    print("Code has successfully been executed.")
except DemoException:
    print("Error: Number should not be 0.")
except NumberFormatException:
    print(num+" is not a number.")

In this code, the value of num that was passed to triggerException() is a string 'sample string' so the NumberFormatException should be triggered.

Output:

sample string is not a number.

In summary, creating custom exceptions in Python is as simple as creating a new class, but with the Exception class as an extra argument in the class definition. The raise keyword is used to trigger exceptions given the Exception Class. The try...except blocks are used to wrap one or more exceptions within a code block and modify what the code does when handling that exception and not just shutting down the program entirely.

In this article let us learn how to manually throw an exception in Python.

How to throw/raise an Exception in Python

An Exception can be manually thrown/raised using the raise statement in Python.

Let us start with a simple example.

raise Exception ('I just raised my 1st ever Exception in Python!')

Running that code will result in an output like below

Traceback (most recent call last):
 File "", line 1, in 
     raise Exception ('I just raised my 1st ever Exception in Python!')
 Exception: I just raised my 1st ever Exception in Python!

As you can see, we have managed to throw an exception using the raise statement! This has caused the interpreter to crash the program just like a runtime error would!

Hence the statement we are looking for here is raise. But this is just the short version of the answer. Read on to find out how exactly to employ this raise statement in your code in a variety of situations.

The rest of the article explains

  • The 3 major syntax/variants of the raise statement
  • When and Where to use each of these syntax and
  • The best practices to follow while using each of these syntax

So, let’s begin!

raise Syntax#1: Raise Exception with a Custom Error Message

The syntax shown in the example below (line 3) is the most common syntax you will see with the raise statement.

x = int(input('Please enter a even number: '))
if ( x % 2 != 0 ):
    raise ValueError('Input is an odd number, cannot continue Execution')
else:
     # continue with whatever you want to do with the even number

In the example above, we are throwing a ValueError with the error message “The value is not as expected”.

For those of you who are very new to Python let us briefly see what ValueError is. According to the official python documentation

ValueError is raised when an operation or function receives an argument that has the right type but an inappropriate value

https://docs.python.org/3/library/exceptions.html#bltin-exceptions

which basically means the passed in argument is of the right type, but the value contained is meaningless to our program.

Running the code in Example-2 above will give you an output like this.

Please enter a even number: 9
 Traceback (most recent call last):
 File "", line 3, in 
     raise ValueError('Input is an odd number, cannot continue Execution')
 ValueError: Input is an odd number, cannot continue Execution

As you can see, the custom message we coded in is printed along with the exception name.

The syntax used in Example-2 is shown below. Replace the terms with the angle brackets ‘<>’ with whatever your program needs!

raise <ExceptionType> (<error message>)

Use this syntax when you wish to raise an Exception and pass a custom error message through that Exception. This custom message can either be sent to an output device to be seen by the user or to a log file, so that you, the programmer, can see these logs later and use the information there for debugging purposes.

In case you wish to catch the raised Exception from the calling code so that you can deal with that instead of ending your program, you can do so as shown in the example below

def checkForDivisibilityBy2():
     x = int(input('Please enter a even number: '))
     if ( x % 2 != 0 ):
         raise ValueError('Input is an odd number, cannot continue Execution')
     else:
         print('The entered number is divisible by 2')

try:
     checkForDivisibilityBy2()
except ValueError as err:
     print (str(err))

The output as you might have expected will look like this.

Please enter a even number: 9
 Input is an odd number, cannot continue Execution

The syntax used in the above example is shown below. Replace the terms with the angle brackets ‘<>’ with whatever your program needs!

except <exception_type> as <exception_instance_name>:
    print ( str (<exception_instance_name>) )

Best Practices for Syntax#1

If you ever need to use this syntax in your Python code, remember these 2 points

  1. Be sure to word-smith a very specific error message, so that the ‘future-you’ or anyone else reading these error messages will understand what went wrong and
  2. Use an appropriate Exception type to raise.

See how ValueError suits this particular program. It is considered best practice to pick an appropriate Exception to raise, else you will end up hiding bugs leading to unreliable programs. We will see an example of such a situation after Syntax#2.

raise Syntax#2: Raise Exception without any Custom messages

Sometime, you may not need to log or print out messages to the user. In those situations you can use the syntax shown in the example below

raise ValueError

The output on the interpreter will look like this

Traceback (most recent call last):
 File "", line 1, in 
     raise ValueError
 ValueError

As you can see, the output has just the Exception class name and no error message.

The syntax used in the above example is shown below. As with previous syntax snippets, replace the terms with the angle brackets ‘<>’ with whatever your program needs!

raise <ExceptionType>

What happens behind the scenes when we use this syntax?

The raise statement will expect the first object passed in to be an Exception object. If we pass a Class name as the argument to raise, the python interpreter will convert the code behind the scenes to be

raise ValueError()

which is a call to the constructor of the ValueError class with no arguments.

Similarly, in Syntax#1, what we wrote was raise followed by a call to the constructor with a string argument which is an attribute meant to be used as the error message. This constructor then returns a Exception object, which is what the raise statement needs!

If you wish to learn more about how this string is used in the error message, read my other article on printing exceptions below

Python Exceptions: Getting and Handling Error Messages as strings.

The class which is passed with the raise statement must be a subclass of the BaseException class, which as the name implies is the base class for all the built-in Exception classes in Python.

You can find all the built-in exception classes that python provides in the python documentation here.

If you scroll down till the bottom of that page you can find the Exception Hierarchy tree as shown in the image below.

So just for fun, to see what happens, let us pass a list object to the raise statement!

list1 = [1,2,3,4]
raise list1

If you run this code, the interpreter will raise a TypeError exception as the interpreter was expecting an object of “Exception type” and we passed in a “list type” object.

Traceback (most recent call last):
 File "", line 1, in 
     raise list1
 TypeError: exceptions must derive from BaseException

Now that we have understood how to use Syntax#2, let us next see when to use this syntax!

When to use Syntax#2 raise statement

Best time to use Syntax#2 is when you can recover from an Exception through code-substitution or default-value substitution. If you haven’t already, I suggest reading my other article which covers the basics of exception handling in Python.

Exceptions in Python: Everything You Need To Know!

In the article given in the link above, the sub-section “Strategy#2″ in the section “3 ways to handle Exceptions” explains how to recover from exceptions.

Syntax#2 best goes with such problems where it is possible to recover from exceptions and continue with the program execution.

Best Practices for Syntax#2 raise statement

As with Syntax#1 try using an appropriate type of Exception here, also make sure the exception you raise is very specific else you may end-up hiding bugs leading to a unreliable program.

Let us see a simple example of such a situation.

raise: How to avoid Hiding Bugs

Consider the snippet below.

def divide(numerator, denominator):
     return int(numerator)/int(denominator)

This function call can produce 2 types of exceptions.

The output below shows the 1st of the 2 types

>> divide(10, 0)
 Traceback (most recent call last):
 File "", line 1, in 
     divide(10, 0)
 File "", line 2, in divide
     return numerator/denominator
 ZeroDivisionError: division by zero

Here we passed in the second argument as 0, and division by zero is not allowed in Math, and this resulted in ZeroDivisionError

The output below shows the 2nd type of exception that the code in Example#6 can produce

>> divide('pizza', 6)
 Traceback (most recent call last):
 File "", line 1, in 
     divide('pizza', 6)
 File "", line 2, in divide
     return numerator/denominator
 TypeError: unsupported operand type(s) for /: 'str' and 'int'

Here we tried to divide a pizza into 6 pieces using our Math function and this resulted in TypeError!

Say for example, when we wrote the code we forgot about ValueError and we wrote code only to handle division by zeros as shown below.

def divide(numerator, denominator):
     if (denominator == 0):
         raise Exception
     else:
         return int(numerator)/int(denominator)
 try:
     x = input('Please enter the Numerator: ')
     y = input('Please enter the Denominator: ')
     print(x, ' / ', y, ' = ', str(divide(x,y)))
 except Exception:
     print("You have entered zero as denominator")

As you can see instead of using ZeroDivisionError type to raise the exception we used Exception type, which is higher in the hierarchy to both TypeError type and ZeroDivisionError type.

Now running the code, to cut a pizza into 6 pieces results in something like this!

Please enter the Numerator: Pizza
 Please enter the Denominator: 6
 You have entered zero as denominator

As you can see the ValueError exception bug is completely hidden due to our poor choice of Exception type.

Instead if you wrote your code like this using ZeroDivisionError

def divide(numerator, denominator):
     if (denominator == 0):
         raise ZeroDivisionError
     else:
         return int(numerator)/int(denominator)
 try:
     x = input('Please enter the Numerator: ')
     y = input('Please enter the Denominator: ')
     print(x, ' / ', y, ' = ', str(divide(x,y)))
 except ZeroDivisionError:
     print("You have entered zero as denominator")

Then if you run the code with bad values, the interpreter will crash the program revealing the ValueError bug as shown below.

Please enter the Numerator: Pizza
 Please enter the Denominator: 6
 Traceback (most recent call last):
 File "", line 4, in 
     print(x, ' / ', y, ' = ', str(divide(x,y)))
 File "", line 5, in divide
     return int(numerator)/int(denominator)
 ValueError: invalid literal for int() with base 10: 'Pizza'

Hence always go for the Exception type which is specific and appropriate for your situation!

raise and User-Defined Exception Types

Next let us see the best-practices to follow when raising user-defined Exception types. Let us start by learning how to make user-defined exceptions.

How to make your own exception?

In Python making your own exception type is super simple with just 2 lines of code

class MyException (Exception):
    pass

Just declare a class that inherits from the built-in Exception class. Then you can raise your exception using Syntax#1 as shown below

>> raise MyException('I am raising my own Exception!!!')
 Traceback (most recent call last):
 File "", line 1, in 
     raise MyException('I am raising my own Exception!!!')
 MyException: I am raising my own Exception!!!

You can also use Syntax#2 as shown below

>> raise MyException
 Traceback (most recent call last):
 File "", line 1, in 
     raise MyException
 MyException

When you should Raise your own custom-defined Exception types and when you should use built-in exceptions?

  • avoid using user-defined Exception types if possible, as python built-in error types are designed to fit almost every use-case and user-defined Exception types can make the code harder to read and maintain.
  • Make sure your exception classes inherit from an appropriate python built-in class
  • Generic error are more likely to hide bugs and are considered bad programming practice hence try to go as specific as you can while choosing exceptions.

Let us next move onto the 3rd, final and even shorter syntax of using the raise statement.

raise Syntax#3: without any arguments

The third syntax is to just use the raise statement with no arguments as shown below.

raise

Let us see an example to see how this can be used.

def reRaiseException():
     try:
         raise ValueError('I am raising a value error for no reason')
     except ValueError as err:
         print('reRaiseException(): ', str(err))
         print ('Re-Raising the exception to the calling code')
         raise
try:
     reRaiseException()
except ValueError as error:
     print('Main code: ', str(error))

Running this code will give an output like this

reRaiseException():  I am raising a value error for no reason
 Re-Raising the exception to the calling code
 Main code:  I am raising a value error for no reason

Here in the function reRaiseException() a ValueError is raised (in Line3) with a custom message and caught by a except clause inside the function. In Line7 the caught exception is re-raised to the calling code.

The except clause in Line10 catches this exception and prints the custom error message passed first on Line3 inside the reRaiseException() function.

One point worth noting is that, if there was no except clause inside the reRaiseException() function, the exception would have been straightaway passed to the main code without the use of the line raise.

Try running the example code below to see what I mean

def reRaiseException():
         raise ValueError('I am raising a value error for no reason')
 try:
     reRaiseException()
 except ValueError as error:
     print('Main code: ', str(error))

The output of the above code is

Main code:  I am raising a value error for no reason

If there was no except clause to catch this one level up, then this exception will crash the program, same as Example 1 in the beginning of the article.

The main reason for the existence of this syntax is because, there are situations, where you might want to do something in the except block inside the reRaiseException() function but you wish to let the the calling code to actually handle that Exception.

In our case we merely printed out 2 more lines before reraising the exception to the main code to demonstrate this point. We will see examples of some situations where this might be useful later in this article.

If no exception is present in the current scope the interpreter will raise a RuntimeError exception indicating that this is an error. This can be easily demonstrated by typing raise and hitting the enter button on the python console.

raise
 Traceback (most recent call last):
 File "", line 1, in 
     raise
 RuntimeError: No active exception to reraise

As you can see the interpreter prints an appropriate error message namely

No active exception to reraise

And that ends our 3rd and final syntax/variants of using the raise statement.

Exception Chaining and raise Statement

Before ending this article, I would like to point out there there are one more syntax that employ the raise statement. A very common use-case involves Exception Chaining.

This comes in 2 sub-variants as shown below.

raise <exception type 1> as <exception type 2>
raise <exception type 1> as None

This is an advanced topic which needs a separate article to explain. Exception Chaining is typically used in big projects with several layers of abstractions, each layer having a set of user-defined Exceptions.

First try and master the above 3 syntax, as those will be used more that 9 out of 10 times you will ever need to use the raise statement.

And with that I will end this article.

Hope you have enjoyed reading this article and got some value from it.

Feel free to share this article with your friends and colleagues.

Be sure to checkout my other article on Exceptions

Exceptions in Python: Everything You Need To Know!

which covers all the basics of exceptions and strategies to handle them!

In the previous tutorial, we learned about different built-in exceptions in Python and why it is important to handle exceptions. .

However, sometimes we may need to create our own custom exceptions that serve our purpose.


Defining Custom Exceptions

In Python, we can define custom exceptions by creating a new class that is derived from the built-in Exception class.

Here’s the syntax to define custom exceptions,

class CustomError(Exception):
    ...
    pass

try:
   ...

except CustomError:
    ...

Here, CustomError is a user-defined error which inherits from the Exception class.

Note:

  • When we are developing a large Python program, it is a good practice to place all the user-defined exceptions that our program raises in a separate file.
  • Many standard modules define their exceptions separately as exceptions.py or errors.py (generally but not always).

Example: Python User-Defined Exception

# define Python user-defined exceptions
class InvalidAgeException(Exception):
    "Raised when the input value is less than 18"
    pass

# you need to guess this number
number = 18

try:
    input_num = int(input("Enter a number: "))
    if input_num < number:
        raise InvalidAgeException
    else:
        print("Eligible to Vote")
        
except InvalidAgeException:
    print("Exception occurred: Invalid Age")

Output

If the user input input_num is greater than 18,

Enter a number: 45
Eligible to Vote

If the user input input_num is smaller than 18,

Enter a number: 14
Exception occurred: Invalid Age

In the above example, we have defined the custom exception InvalidAgeException by creating a new class that is derived from the built-in Exception class.

Here, when input_num is smaller than 18, this code generates an exception.

When an exception occurs, the rest of the code inside the try block is skipped.

The except block catches the user-defined InvalidAgeException exception and statements inside the except block are executed.


Customizing Exception Classes

We can further customize this class to accept other arguments as per our needs.

To learn about customizing the Exception classes, you need to have the basic knowledge of Object-Oriented programming.

Visit Python Object Oriented Programming to learn about Object-Oriented programming in Python.

Let’s see an example,

class SalaryNotInRangeError(Exception):
    """Exception raised for errors in the input salary.

    Attributes:
        salary -- input salary which caused the error
        message -- explanation of the error
    """

    def __init__(self, salary, message="Salary is not in (5000, 15000) range"):
        self.salary = salary
        self.message = message
        super().__init__(self.message)


salary = int(input("Enter salary amount: "))
if not 5000 < salary < 15000:
    raise SalaryNotInRangeError(salary)

Output

Enter salary amount: 2000
Traceback (most recent call last):
  File "<string>", line 17, in <module>
    raise SalaryNotInRangeError(salary)
__main__.SalaryNotInRangeError: Salary is not in (5000, 15000) range

Here, we have overridden the constructor of the Exception class to accept our own custom arguments salary and message.

Then, the constructor of the parent Exception class is called manually with the self.message argument using super().

The custom self.salary attribute is defined to be used later.

The inherited __str__ method of the Exception class is then used to display the corresponding message when SalaryNotInRangeError is raised.

Понравилась статья? Поделить с друзьями:
  • Python raise error code
  • Python raise custom error
  • Python psycopg2 install error
  • Python proxy ssl error
  • Python protocol error