Learning Python Part-25: Error and Exceptions

When writing a program, most of the times we will encounter errors. There are various possible reasons for which errors are generated. 


There are  two distinguishable types of errors: syntax errors and exceptions.

Syntax Erros:

  • Not following the proper syntax of the programming language will generate a syntax error. It is also known as parsing error.
  • Example:

if a < 5
    print(a)

  • In above example, colon “:”  is missing in the if statement after 5.

Exceptions:

  • Even after following  correct syntax of statements or expressions, it may cause an error when executing the program. 
  • Errors detected during execution are called exceptions
  • For example, Exception occurs when a file we try to open does not exist will raise FileNotFoundError or dividing a number by zero will raise ZeroDivisionError and so on.
Example 1:

10 / 0    # running this code will raise below exception.

Traceback (most recent call last):
         File “/Users/eddydesh/PycharmProjects/website/main.py”, line 1, in
              10/0
ZeroDivisionError: division by zero

Example2:


open(“testfile.txt”)      # Trying to open non existing file

Traceback (most recent call last):
      File “/Users/eddydesh/PycharmProjects/website/main.py”, line 1, in
           open(“testfile.txt”)
FileNotFoundError: [Errno 2] No such file or directory: ‘testfile.txt’ 

  • Whenever these type of runtime error occur, Python creates an exception object. And if it is not handled properly, it prints a traceback to error along with details of why error occurred and program is halted.

Python Built-in Exceptions:

  • There are plenty of built-in exceptions in Python that are raised when corresponding errors occur. 
  • We can view all the built-in exceptions using the local() built-in functions as follows.

>>> locals()


{‘__name__’: ‘__main__’, ‘__doc__’: None, ‘__package__’: None, ‘__loader__’: , ‘__spec__’: None, ‘__annotations__’: {}, ‘__builtins__’: , ‘__file__’: ‘/Users/eddydesh/PycharmProjects/website/main.py’, ‘__cached__’: None, ‘a’: {…}}

  • local() returns a dictionary of built-in exceptions, functions and attributes.
  • For getting below list, use 

print(dir(locals()[‘__builtins__’]))



Python Exception Handling:

  • Python built-in exceptions forces program to output an error when something goes wrong in program. 
  • When exceptions occur, it causes the current process to halt and passes it to the calling process until it is handled.  If not handled, program will crash.
  • For example, if function A calls function B which in turn calls function C and an exception occurs in function C. If it is not handled in C, the exception passes to B and then to A.
  • If not handled at any level, an error message generated and program comes to an unexpected halt.

Catching Exceptions in Python:

  • It is very much possible to write programs that handle selected exceptions. 
  • In Python, exceptions can be handled using a try statement.
  • A critical operation which can raise exception is placed inside the try clause and the code that handles exception is written in except clause.
  • It is up to programmer, what operations will be performed once exception is caught. 
  • Example:

while True:

           try: 
                x = int(input(“Please enter a number: “))
                print(x, ” is an integer”)
                break 
           except: 
                print(“Invalid inout. Try again…”)

Catching Specific Exceptions in Python:

  • In previous example, we did not mention any exception in the except clause, which is not a ideal programming practice as it will catch all exceptions and handle every case in the same way. 
  • We can specify which exceptions an except clause will catch.
  • A try clause can have any number of except clause to handle them differently but only one will be executed in case an exception occurs.
  • We can use a tuple of values to specify multiple exceptions in an except clause. 
  • Example:

while True:
          try:
                 x = int(input(“Please enter first number: “))
                 y = int(input(“Please enter second number: “))
                 print(“Division is: “, x/y)
                 break
          except ValueError:
                 print(“Invalid inout. Try again…”)
          except ZeroDivisionError:
                 print(“Its a zero division error. Cannot devide by 0. Try again”)


try…finally:

  • The try statement in Python can have an optional finally clause. 
  • This clause is executed no matter what, and is generally used to release external resources.
  • For example one use case can be, we may be working with a file and once we are done writing changes, we want to close the file
  • In these kind of operations, we must release resources once used, regardless of operation was successful or not. 
  • These sort of actions are performed in the finally clause for guaranteed execution.
  • Example of file operations.

try:
    f = open(“test_file.txt”, encoding = ‘utf-8’)
    # perform file operations
finally:
    f.close()

  • This makes sure the file is closed even if an exception occurs.

Python Custom(User Defined) Exceptions:

  • Python has many built-in exceptions which forces program to output an error.
  • However, at times we may need to create custom exceptions that serves specific purpose.
  • In Python, users can define such exceptions by creating a new class. 
  • This exception class has to be derived, either directly or indirectly, from Exception class. 
  • Most of the built-in exceptions are also derived form this class.
Example:

class CustomError(Exception):
         pass
raise CustomError
raise CustomError(“An error occurred”) 


# Output of first raise:
Traceback (most recent call last):
__main__.CustomError

# Output of second raise:
Traceback (most recent call last):
__main__.CustomError: An error occurred

  • Here, we have created a user-defined exception called CustomError which is derived from the Exception class. 
  • This new exception can be raised, like any other exceptions, using the raise statement with an error message(optional).
  • When developing a large Python program, best practice would be to place all the user-defined exceptions in a separate file(Module) something like exceptions.py. Later it can be imported to program.
Raising Exceptions:
  • Until now we discussed about catching the exceptions. However, we may want to raise error intentionally when required.
  • We can also optionally pass in value to the exception to clarify why that exception was raised.

a = ‘python’

if not type(a) is int:
      raise TypeError(“Enter integers only”)



Leave a Reply