Python raise custom error

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

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

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.

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')

  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.

Summary: in this tutorial, you’ll learn how to define Python custom exception classes.

Introduction to the Python custom exception

To create a custom exception class, you define a class that inherits from the built-in Exception class or one of its subclasses such as ValueError class:

Python Custom Exception

The following example defines a CustomException class that inherits from the Exception class:

class CustomException(Exception): """ my custom exception class """

Code language: Python (python)

Note that the CustomException class has a docstring that behaves like a statement. Therefore, you don’t need to add the pass statement to make the syntax valid.

To raise the CustomException, you use the raise statement. For example, the following uses the raise statement to raise the CustomException:

class CustomException(Exception): """ my custom exception class """ try: raise CustomException('This is my custom exception') except CustomException as ex: print(ex)

Code language: Python (python)

Output:

This is my custom exception

Code language: Python (python)

Like standard exception classes, custom exceptions are also classes. Hence, you can add functionality to the custom exception classes like:

  • Adding attributes and properties.
  • Adding methods e.g., log the exception, format the output, etc.
  • Overriding the __str__ and __repr__ methods
  • And doing anything else that you can do with regular classes.

In practice, you’ll want to keep the custom exceptions organized by creating a custom exception hierarchy. The custom exception hierarchy allows you to catch exceptions at multiple levels, like the standard exception classes.

Suppose you need to develop a program that converts a temperature from Fahrenheit to Celsius.

The minimum and maximum values of a temperature in Fahrenheit are 32 and 212. If users enter a value that is not in this range, you want to raise a custom exception e.g., FahrenheitError.

Define the FahrenheitError custom exception class

The following defines the FahrenheitError exception class:

class FahrenheitError(Exception): min_f = 32 max_f = 212 def __init__(self, f, *args): super().__init__(args) self.f = f def __str__(self): return f'The {self.f} is not in a valid range {self.min_f, self.max_f}'

Code language: Python (python)

How it works.

  • First, define the FahrenheitError class that inherits from the Exception class.
  • Second, add two class attributes min_f and max_f that represent the minimum and maximum Fahrenheit values.
  • Third, define the __init__ method that accepts a Fahrenheit value (f) and a number of position arguments (*args). In the __init__ method, call the __init__ method of the base class. Also, assign the f argument to the f instance attribute.
  • Finally, override the __str__ method to return a custom string representation of the class instance.

Define the fahrenheit_to_celsius function

The following defines the fahrenheit_to_celsius function that accepts a temperature in Fahrenheit and returns a temperature in Celcius:

def fahrenheit_to_celsius(f: float) -> float: if f < FahrenheitError.min_f or f > FahrenheitError.max_f: raise FahrenheitError(f) return (f - 32) * 5 / 9

Code language: Python (python)

The fahrenheit_to_celsius function raises the FahrenheitError excpetion if the input temperature is not in the valid range. Otherwise, it converts the temperature from Fahrenheit to Celcius.

Create the main program

The following main program uses the fahrenheit_to_celsius function and the FahrenheitError custom exception class:

if __name__ == '__main__': f = input('Enter a temperature in Fahrenheit:') try: f = float(f) except ValueError as ex: print(ex) else: try: c = fahrenheit_to_celsius(float(f)) except FahrenheitError as ex: print(ex) else: print(f'{f} Fahrenheit = {c:.4f} Celsius')

Code language: Python (python)

How it works.

First, prompt users for a temperature in Fahrenheit.

f = input('Enter a temperature in Fahrenheit:')

Code language: Python (python)

Second, convert the input value into a float. If the float() cannot convert the input value, the program will raise a ValueError exception. In this case, it displays the error message from the ValueError exception:

try: f = float(f) # ... except ValueError as ex: print(ex)

Code language: Python (python)

Third, convert the temperature to Celsius by calling the fahrenheit_to_celsius function and print the error message if the input value is not a valid Fahrenheit value:

try: c = fahrenheit_to_celsius(float(f)) except FahrenheitError as ex: print(ex) else: print(f'{f} Fahrenheit = {c:.4f} Celsius')

Code language: Python (python)

Put it all together

class FahrenheitError(Exception): min_f = 32 max_f = 212 def __init__(self, f, *args): super().__init__(args) self.f = f def __str__(self): return f'The {self.f} is not in a valid range {self.min_f, self.max_f}' def fahrenheit_to_celsius(f: float) -> float: if f < FahrenheitError.min_f or f > FahrenheitError.max_f: raise FahrenheitError(f) return (f - 32) * 5 / 9 if __name__ == '__main__': f = input('Enter a temperature in Fahrenheit:') try: f = float(f) except ValueError as ex: print(ex) else: try: c = fahrenheit_to_celsius(float(f)) except FahrenheitError as ex: print(ex) else: print(f'{f} Fahrenheit = {c:.4f} Celsius')

Code language: Python (python)

Summary

  • Subclass the Exception class or one of its subclasses to define a custom exception class.
  • Create a exception class hierarchy to make the exception classes more organized and catch exceptions at multiple levels.

Did you find this tutorial helpful ?

Понравилась статья? Поделить с друзьями:
  • Python psycopg2 install error
  • Python proxy ssl error
  • Python protocol error
  • Python print encode error
  • Python pptx как изменить шрифт