PYnative

Python Programming

  • Learn Python
  • Exercises
  • Quizzes
  • Code Editor
  • Tricks
Home » Python » Python Exceptions and Errors

Python Exceptions and Errors

Updated on: March 25, 2021 | 1 Comment

In this article, you will learn error and exception handling in Python.

By the end of the article, you’ll know:

  • How to handle exceptions using the try, except, and finally statements
  • How to create a custom exception
  • How to raise an exceptions
  • How to use built-in exception effectively to build robust Python programs
Python Exceptions
Python Exceptions

Table of contents

  • What are Exceptions?
    • Why use Exception
  • What are Errors?
    • Syntax error
    • Logical errors (Exception)
  • Built-in Exceptions
  • The try and except Block to Handling Exceptions
    • Catching Specific Exceptions
    • Handle multiple exceptions with a single except clause
  • Using try with finally
  • Using try with else clause
  • Raising an Exceptions
  • Exception Chaining
  • Custom and User-defined Exceptions
    • Customizing Exception Classes
  • Exception Lifecycle
  • Warnings

What are Exceptions?

An exception is an event that occurs during the execution of programs that disrupt the normal flow of execution (e.g., KeyError Raised when a key is not found in a dictionary.) An exception is a Python object that represents an error..

In Python, an exception is an object derives from the BaseException class that contains information about an error event that occurred within a method. Exception object contains:

  • Error type (exception name)
  • The state of the program when the error occurred
  • An error message describes the error event.

Exception are useful to indicate different types of possible failure condition.

For example, bellow are the few standard exceptions

  • FileNotFoundException
  • ImportError
  • RuntimeError
  • NameError
  • TypeError

In Python, we can throw an exception in the try block and catch it in except block.

Why use Exception

  • Standardized error handling: Using built-in exceptions or creating a custom exception with a more precise name and description, you can adequately define the error event, which helps you debug the error event.
  • Cleaner code: Exceptions separate the error-handling code from regular code, which helps us to maintain large code easily.
  • Robust application: With the help of exceptions, we can develop a solid application, which can handle error event efficiently
  • Exceptions propagation: By default, the exception propagates the call stack if you don’t catch it. For example, if any error event occurred in a nested function, you do not have to explicitly catch-and-forward it; automatically, it gets forwarded to the calling function where you can handle it.
  • Different error types: Either you can use built-in exception or create your custom exception and group them by their generalized parent class, or Differentiate errors by their actual class

What are Errors?

On the other hand, An error is an action that is incorrect or inaccurate. For example, syntax error. Due to which the program fails to execute.

The errors can be broadly classified into two types:

  1. Syntax errors
  2. Logical errors

Syntax error

The syntax error occurs when we are not following the proper structure or syntax of the language. A syntax error is also known as a parsing error.

When Python parses the program and finds an incorrect statement it is known as a syntax error. When the parser found a syntax error it exits with an error message without running anything.

Common Python Syntax errors:

  • Incorrect indentation
  • Missing colon, comma, or brackets
  • Putting keywords in the wrong place.

Example

print("Welcome to PYnative")
    print("Learn Python with us..")

Output

print("Learn Python with us..")
    ^
IndentationError: unexpected indent

Logical errors (Exception)

Even if a statement or expression is syntactically correct, the error that occurs at the runtime is known as a Logical error or Exception. In other words, Errors detected during execution are called exceptions.

Common Python Logical errors:

  • Indenting a block to the wrong level
  • using the wrong variable name
  • making a mistake in a boolean expression

Example

a = 10
b = 20
print("Addition:", a + c)

Output

print("Addition:", a + c)
NameError: name 'c' is not defined

Built-in Exceptions

The below table shows different built-in exceptions.

Python automatically generates many exceptions and errors. Runtime exceptions, generally a result of programming errors, such as:

  • Reading a file that is not present
  • Trying to read data outside the available index of a list
  • Dividing an integer value by zero
ExceptionDescription
AssertionErrorRaised when an assert statement fails.
AttributeErrorRaised when attribute assignment or reference fails.
EOFErrorRaised when the input() function hits the end-of-file condition.
FloatingPointErrorRaised when a floating-point operation fails.
GeneratorExitRaise when a generator’s close() method is called.
ImportErrorRaised when the imported module is not found.
IndexErrorRaised when the index of a sequence is out of range.
KeyErrorRaised when a key is not found in a dictionary.
KeyboardInterruptRaised when the user hits the interrupt key (Ctrl+C or Delete)
MemoryErrorRaised when an operation runs out of memory.
NameErrorRaised when a variable is not found in the local or global scope.
OSErrorRaised when system operation causes system related error.
ReferenceErrorRaised when a weak reference proxy is used to access a garbage collected referent.
Python Built-in Exceptions

Example: The FilenotfoundError is raised when a file in not present on the disk

fp = open("test.txt", "r")
if fp:
    print("file is opened successfully")

Output:

FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'

The try and except Block to Handling Exceptions

When an exception occurs, Python stops the program execution and generates an exception message. It is highly recommended to handle exceptions. The doubtful code that may raise an exception is called risky code.

To handle exceptions we need to use try and except block. Define risky code that can raise an exception inside the try block and corresponding handling code inside the except block.

Syntax

try :
    # statements in try block
except :
    # executed when exception occured in try block
try-except block
try-except block

The try block is for risky code that can raise an exception and the except block to handle error raised in a try block. For example, if we divide any number by zero, try block will throw ZeroDivisionError, so we should handle that exception in the except block.

When we do not use try…except block in the program, the program terminates abnormally, or it will be nongraceful termination of the program.

Now let’s see the example when we do not use try…except block for handling exceptions.

Example:

a = 10
b = 0
c = a / b
print("a/b = %d" % c)

Output

Traceback (most recent call last):
  File "E:/demos/exception.py", line 3, in <module>
    c = a / b
ZeroDivisionError: division by zero

We can see in the above code when we are divided by 0; Python throws an exception as ZeroDivisionError and the program terminated abnormally.

We can handle the above exception using the try…except block. See the following code.

Example

try:
    a = 10
    b = 0
    c = a/b
    print("The answer of a divide by b:", c)
except:
    print("Can't divide with zero. Provide different number")

Output

Can't divide with zero. Provide different number

Catching Specific Exceptions

We can also catch a specific exception. In the above example, we did not mention any specific exception in the except block. Catch all the exceptions and handle every exception is not good programming practice.

It is good practice to specify an exact exception that the except clause should catch. For example, to catch an exception that occurs when the user enters a non-numerical value instead of a number, we can catch only the built-in ValueError exception that will handle such an event properly.

We can specify which exception except block should catch or handle. A try block can be followed by multiple numbers of except blocks to handle the different exceptions. But only one exception will be executed when an exception occurs.

Example

In this example, we will ask the user for the denominator value. If the user enters a number, the program will evaluate and produce the result.

If the user enters a non-numeric value then, the try block will throw a ValueError exception, and we can catch that using a first catch block ‘except ValueError’ by printing the message ‘Entered value is wrong’.

And suppose the user enters the denominator as zero. In that case, the try block will throw a ZeroDivisionError, and we can catch that using a second catch block by printing the message ‘Can’t divide by zero’.

try:
    a = int(input("Enter value of a:"))
    b = int(input("Enter value of b:"))
    c = a/b
    print("The answer of a divide by b:", c)
except ValueError:
    print("Entered value is wrong")
except ZeroDivisionError:
    print("Can't divide by zero")

Output 1:

Enter value of a:Ten
Entered value is wrong

Output 2:

Enter value of a:10
Enter value of b:0
Can't divide by zero

Output 3:

Enter value of a:10
Enter value of b:2
The answer of a divide by b: 5.0

Handle multiple exceptions with a single except clause

We can also handle multiple exceptions with a single except clause. For that, we can use an tuple of values to specify multiple exceptions in an except clause.

Example

Let’s see how to specifiy two exceptions in the single except clause.

try:
    a = int(input("Enter value of a:"))
    b = int(input("Enter value of b:"))
    c = a / b
    print("The answer of a divide by b:", c)
except(ValueError, ZeroDivisionError):
    print("Please enter a valid value")

Using try with finally

Python provides the finally block, which is used with the try block statement. The finally block is used to write a block of code that must execute, whether the try block raises an error or not.

Mainly, the finally block is used to release the external resource. This block provides a guarantee of execution.

try-except-finally block
try-except-finally block

Clean-up actions using finally

Sometimes we want to execute some action at any cost, even if an error occurred in a program. In Python, we can perform such actions using a finally statement with a try and except statement.

The block of code written in the finally block will always execute even there is an exception in the try and except block.

If an exception is not handled by except clause, then finally block executes first, then the exception is thrown. This process is known as clean-up action.

Syntax

try:    
    # block of code     
    # this may throw an exception    
finally:    
    # block of code    
    # this will always be executed 
    # after the try and any except block   

Example

try:
    a = int(input("Enter value of a:"))
    b = int(input("Enter value of b:"))
    c = a / b
    print("The answer of a divide by b:", c)

except ZeroDivisionError:
    print("Can't divide with zero")
finally:
    print("Inside a finally block")

Output 1:

Enter value of a:20
Enter value of b:5
The answer of a divide by b: 4.0
Inside a finally block

Output 2:

Enter value of a:20
Enter value of b:0
Can't divide with zero
Inside a finally block

In the above example, we can see we divide a number by 0 and get an error, and the program terminates normally. In this case, the finally block was also executed.

Using try with else clause

Sometimes we might want to run a specific block of code. In that case, we can use else block with the try-except block. The else block will be executed if and only if there are no exception is the try block. For these cases, we can use the optional else statement with the try statement.

Why to use else block with try?

Use else statemen with try block to check if try block executed without any exception or if you want to run a specific code only if an exception is not raised

try-else block

Syntax

try:    
    # block of code     
except Exception1:    
    # block of code     
else:    
    # this code executes when exceptions not occured    
  • try: The try block for risky code that can throw an exception.
  • except: The except block to handle error raised in a try block.
  • else: The else block is executed if there is no exception.

Example

try:
    a = int(input("Enter value of a:"))
    b = int(input("Enter value of b:"))
    c = a / b
    print("a/b = %d" % c)

except ZeroDivisionError:
    print("Can't divide by zero")
else:
    print("We are in else block ")

Output 1

Enter value of a: 20
Enter value of b:4
a/b = 5
We are in else block 

Output 2

Enter value of a: 20
Enter value of b:0
Can't divide by zero

Raising an Exceptions

In Python, the raise statement allows us to throw an exception. The single arguments in the raise statement show an exception to be raised. This can be either an exception object or an Exception class that is derived from the Exception class.

The raise statement is useful in situations where we need to raise an exception to the caller program. We can raise exceptions in cases such as wrong data received or any validation failure.

Follow the below steps to raise an exception:

  • Create an exception of the appropriate type. Use the existing built-in exceptions or create your won exception as per the requirement.
  • Pass the appropriate data while raising an exception.
  • Execute a raise statement, by providing the exception class.

The syntax to use the raise statement is given below.

raise Exception_class,<value>  

Example

In this example, we will throw an exception if interest rate is greater than 100.

def simple_interest(amount, year, rate):
    try:
        if rate > 100:
            raise ValueError(rate)
        interest = (amount * year * rate) / 100
        print('The Simple Interest is', interest)
        return interest
    except ValueError:
        print('interest rate is out of range', rate)

print('Case 1')
simple_interest(800, 6, 8)

print('Case 2')
simple_interest(800, 6, 800)

Output:

Case 1
The Simple Interest is 384.0

Case 2
interest rate is out of range 800

Exception Chaining

The exception chaining is available only in Python 3. The raise statements allow us as optional from statement, which enables chaining exceptions. So we can implement exception chaining in python3 by using raise…from clause to chain exception.

When exception raise, exception chaining happens automatically. The exception can be raised inside except or finally block section. We also disabled exception chaining by using from None idiom.

Example

try:
    a = int(input("Enter value of a:"))
    b = int(input("Enter value of b:"))
    c = a/b
    print("The answer of a divide by b:", c)
except ZeroDivisionError as e:
    raise ValueError("Division failed") from e

# Output: Enter value of a:10
# Enter value of b:0
# ValueError: Division failed

In the above example, we use exception chaining using raise...from clause and raise ValueError division failed.

Custom and User-defined Exceptions

Sometimes we have to define and raise exceptions explicitly to indicate that something goes wrong. Such a type of exception is called a user-defined exception or customized exception.

The user can define custom exceptions by creating a new class. This new exception class has to derive either directly or indirectly from the built-in class Exception. In Python, most of the built-in exceptions also derived from the Exception class.

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

class ValueTooSmallError(Error):
    """Raised when the input value is small"""
    pass

class ValueTooLargeError(Error):
    """Raised when the input value is large"""
    pass

while(True):
    try:
        num = int(input("Enter any value in 10 to 50 range: "))
        if num < 10:
            raise ValueTooSmallError
        elif num > 50:
            raise ValueTooLargeError
        break
    except ValueTooSmallError:
            print("Value is below range..try again")

    except ValueTooLargeError:
            print("value out of range...try again")

print("Great! value in correct range.")

Output

Enter any value in 10 to 50 range: 5
Value is below range..try again

Enter any value in 10 to 50 range: 60
value out of range...try again

Enter any value in 10 to 50 range: 11
Great! value in correct range.

In the above example, we create two custom classes or user-defined classes with names, ValueTooSmallError and ValueTooLargeError.When the entered value is below the range, it will raise ValueTooSmallError and if the value is out of then, it will raise ValueTooLargeError.

Customizing Exception Classes

We can customize the classes by accepting arguments as per our requirements. Any custom exception class must be Extending from BaseException class or subclass of BaseException.

In the above example, we create a custom class that is inherited from the base class Exception. This class takes one argument age. When entered age is negative, it will raise NegativeAgeError.

class NegativeAgeError(Exception):

    def __init__(self, age, ):
        message = "Age should not be negative"
        self.age = age
        self.message = message

age = int(input("Enter age: "))
if age < 0:
    raise NegativeAgeError(age)
# Output:
# raise NegativeAgeError(age)
# __main__.NegativeAgeError: -9

Output:

Enter age: -28
 Traceback (most recent call last):
   File "E:/demos/exception.py", line 11, in 
     raise NegativeAgeError(age)
 main.NegativeAgeError: -28

Done

Exception Lifecycle

  • When an exception is raised, The runtime system attempts to find a handler for the exception by backtracking the ordered list of methods calls. This is known as the call stack.
  • If a handler is found (i.e., if except block is located), there are two cases in the except block; either exception is handled or possibly re-thrown.
  • If the handler is not found (the runtime backtracks to the method chain’s last calling method), the exception stack trace is printed to the standard error console, and the application stops its execution.

Example

def sum_of_list(numbers):
    return sum(numbers)

def average(sum, n):
    # ZeroDivisionError if list is empty
    return sum / n

def final_data(data):
    for item in data:
        print("Average:", average(sum_of_list(item), len(item)))

list1 = [10, 20, 30, 40, 50]
list2 = [100, 200, 300, 400, 500]
# empty list
list3 = []
lists = [list1, list2, list3]
final_data(lists)

Output

Average: 30.0
Traceback (most recent call last):
File "E:/demos/exceptions.py", line 17, in
final_data(lists)
File "E:/demos/exceptions.py", line 11, in final_data
print("Average:", average(sum_of_list(item), len(item)))
Average: 300.0
File "E:/demos/exceptions.py", line 6, in average
return sum / n
ZeroDivisionError: division by zero

The above stack trace shows the methods that are being called from main() until the method created an exception condition. It also shows line numbers.

Warnings

Several built-in exceptions represent warning categories. This categorization is helpful to be able to filter out groups of warnings.

The warning doesn’t stop the execution of a program it indicates the possible improvement

Below is the list of warning exception

Waring ClassMeaning
WarningBase class for warning categories
UserWarningBase class for warnings generated by user code
DeprecationWarningWarnings about deprecated features
PendingDeprecationWarningWarnings about features that are obsolete and expected to be deprecated in the future, but are not deprecated at the moment.
SyntaxWarningWarnings about dubious syntax
RuntimeWarningWarnings about the dubious runtime behavior
FutureWarningWarnings about probable mistakes in module imports
ImportWarningWarnings about probable mistakes in module imports
UnicodeWarningWarnings related to Unicode data
BytesWarningWarnings related to bytes and bytearray.
ResourceWarningWarnings related to resource usage
Python Exception warnings

Filed Under: Python, Python Basics

Did you find this page helpful? Let others know about it. Sharing helps me continue to create free Python resources.

TweetF  sharein  shareP  Pin

About Vishal

Founder of PYnative.com I am a Python developer and I love to write articles to help developers. Follow me on Twitter. All the best for your future Python endeavors!

Related Tutorial Topics:

Python Python Basics

Python Exercises and Quizzes

Free coding exercises and quizzes cover Python basics, data structure, data analytics, and more.

  • 15+ Topic-specific Exercises and Quizzes
  • Each Exercise contains 10 questions
  • Each Quiz contains 12-15 MCQ
Exercises
Quizzes

Posted In

Python Python Basics
TweetF  sharein  shareP  Pin

  Python Tutorials

  • Get Started with Python
  • Python Statements
  • Python Comments
  • Python Keywords
  • Python Variables
  • Python Operators
  • Python Data Types
  • Python Casting
  • Python Control Flow statements
  • Python For Loop
  • Python While Loop
  • Python Break and Continue
  • Python Nested Loops
  • Python Input and Output
  • Python range function
  • Check user input is String or Number
  • Accept List as a input from user
  • Python Numbers
  • Python Lists
  • Python Tuples
  • Python Sets
  • Python Dictionaries
  • Python Functions
  • Python Modules
  • Python isinstance()
  • Python Object-Oriented Programming
  • Python Exceptions
  • Python Exercise for Beginners
  • Python Quiz for Beginners

All Python Topics

Python Basics Python Exercises Python Quizzes Python File Handling Python OOP Python Date and Time Python Random Python Regex Python Pandas Python Databases Python MySQL Python PostgreSQL Python SQLite Python JSON

About PYnative

PYnative.com is for Python lovers. Here, You can get Tutorials, Exercises, and Quizzes to practice and improve your Python skills.

Explore Python

  • Learn Python
  • Python Basics
  • Python Databases
  • Python Exercises
  • Python Quizzes
  • Online Python Code Editor
  • Python Tricks

Follow Us

To get New Python Tutorials, Exercises, and Quizzes

  • Twitter
  • Facebook
  • Sitemap

Legal Stuff

  • About Us
  • Contact Us

We use cookies to improve your experience. While using PYnative, you agree to have read and accepted our Terms Of Use, Cookie Policy, and Privacy Policy.

Copyright © 2018–2023 pynative.com