A Comprehensive Guide for Understanding Errors and Exception Handling in Python
Demystifying Errors and Exception Handling in Python Programming
In this article we'll cover in-depth about errors and exceptions in Python programming. It is most times unavoidable to build or use applications without coming across errors. Python interpreter uses the try....except code block to handle exceptions that may occur during program execution.
Error
Error is the failure, issues, or problems encountered while developing, debugging or using an an application that causes it not to function properly or as designed. The error could either be a syntax error and exception.
Syntax Error
A syntax error is an error that occurs when there's a violation of the python's coding structure or rule. For example:
def error_log():
print("error logger for python)
The code above will throw an error because according to syntax rule a string literal must be terminated. There's a ^
symbol pointing where the unterminated string literal is spotted with the line number and the SyntaxError
name of the error with the message.
Exceptions
Exceptions are errors that are detected or that occurs during the execution of a program. There are different types of exception which is usually indicated in the error message. Exception messages can be defined by users (developers). In Python, built-in identifiers are standard exception names which is different from reserved keywords. Here's the basic structure of try...except in Python.
try:
# code to execute with possibilities of causing exception
except:
# code to execute if an exception was caught
Examples of built-in Exception error in Python Programming:
FileNotFoundError
this exception is caught when a file is not found.
ZeroDivisionError
this exception is caught when there's an attempt to divide a number by zero.
ImportError
this exception is caught when an imported module is not found.
- To view all the list of built-in exception in Python
print(dir(locals()['__builtins__']))
List of Python's built-in exceptions can be found here
Exception Handling
Python uses the try...except keywords to handle exceptions.
For example: the code below is correct syntax wise but during execution it'll throw an exception called NameError
because it cannot find the error_logg() function in the program.
def error_log():
print("error logger for python")
error_logg()
Try....Except
try:
def error_log():
print("error logger for python")
error_logg()
except Exception:
print("This a cleaner way to return exception errors")
The codes between the try
and except
keyword is executed first. If an exception occurs during the execution it skips to find if the error type matches the exception named after the except
keyword. An unhandled exception occurs and execution stops with an error message if no error type | handler is matched after passing it to the outer try statement.
Catching Specific Exceptions in Python
try:
def error_log():
print("error logger for python")
error_logg()
#NameError is a used to catch a specific exception when a name is not found.
except NameError:
print("This a cleaner way to return exception errors")
To define handlers for different types of exceptions, a try statement may contain more than one except clause. The exception can take in multiple type as a parenthesized tuple, for example:
try:
def error_log():
print("error logger for python")
f = open("users.txt")
except (RuntimeError, TypeError, NameError, FileNotFoundError) as e:
print(e)
#[Errno 2] No such file or directory: 'users.txt'
- Example 2
using the parenthesized tuple argument to match the exception type for NameError
try:
def error_log():
print("error logger for python")
f = open("user.txt")
error_logg()
except (RuntimeError, TypeError, NameError, FileNotFoundError) as e:
print(e)
#name 'error_logg' is not defined
The Exception
keyword is used to specify a general error response. The program stops when it encounters the Exception
type as the first specific. It should be defined after the check on the specific type of exception errors.
try:
def error_log():
print("error logger for python")
error_log()
f = open('user.txt')
except NameError:
print("This is an error returned when it matches the NameError exception")
except Exception:
print("General response when no specific exception clause is matched")
#error logger for python
#General response when no specific exception clause is matched
Displaying the error from the exception
The as e
after the except value is used to display the Python exception message in a more readable format.
try:
def error_log():
print("error logger for python")
error_log()
f = open('user.txt')
except NameError as e:
print(e)
except Exception as e:
print(e)
# error logger for python
#[Errno 2] No such file or directory: 'user.txt'
The error above is more readable compared to the screenshot below:
def error_log():
print("error logger for python")
error_log()
f = open('user.txt')
Try...except...Else
The else:
execute the the code within it if no error is caught in the try
clause or if no exception was thrown.
try:
def error_log():
print("error logger for python")
except NameError as e:
print(e)
except Exception as e:
print(e)
else:
error_log()
#error logger for python
Try...except...else...finally
The code in the finally
gets executed with or without any exception. The finally
runs even If the code between the try and except keyword gets executed or the except throws an error.
- The code in the
finally
gets executed even when no exception was caught.
try:
def error_log():
print("error logger for python")
except NameError as e:
print(e)
except Exception as e:
print(e)
else:
error_log()
finally:
print("Something to be done to keep things in order")
#error logger for python
#Something to be done to keep things in order
- In the example below: the code in the
finally
gets executed even with theNameError:
exception that is thrown.
try:
def error_log():
print("error logger for python")
error_logg()
except NameError as e:
print(e)
except Exception as e:
print(e)
else:
print("A display if the try works fine")
finally:
print("Something to be done to keep things in order")
# name 'error_logg' is not defined
# Something to be done to keep things in order
Nested try.....except
The try....except
can be nested. The code below displays a nested try....except in the else block. If no error was caught in the outer try
the code (try....except block) in the else
will be executed.
try:
def error_log():
print("error logger for python")
f = open("user.txt")
except (RuntimeError, TypeError, NameError, FileNotFoundError) as e:
print(e)
else:
try:
f = open("users.txt")
print(f.read())
except Exception as e:
print(e)
#[Errno 2] No such file or directory: 'users.txt'
Manually Raising Exception
Exception can be raised within the try...except block
. In the example below: an Exception is raised if the file name is the same.
try:
def error_log():
print("error logger for python")
f = open("user.txt")
if f.name == "user.txt":
raise Exception("File not found!")
except NameError as e:
print(e)
except Exception as e:
print(e)
else:
print("A display if the try works fine")
finally:
print("Something to be done to keep things in order")
# File not found!
# Something to be done to keep things in order
Custom (User) - Defined Exception
A user can define a custom exception handler. The exception can be derived from the Exception class directly or indirectly. It's best to define custom exceptions with names ending with Error
similar to the standard built-in exceptions. It uses the object oriented programming style.
- Returning a custom message through argument
class EmptyError(RuntimeError):
# Constructor
def __init__(self, value):
self.value = value
# __str__ is to return the argument value
def __str__(self):
return(repr(self.value))
try:
var = ""
raise EmptyError("The variable is empty")
except (EmptyError) as e:
print(e)
#'The variable is empty'
- The above code can still be achieved in the format below
class EmptyError(RuntimeError):
pass
try:
var = ""
raise EmptyError("The variable is empty")
except (EmptyError) as e:
print(e)
#The variable is empty
- For fixed message when defining a custom exception
class EmptyError(RuntimeError):
def __init__(self):
super().__init__("The variable is not greater than zero!!!")
try:
var = 0
if var > 0:
print("No exception")
else:
raise EmptyError()
except (EmptyError) as e:
print(str(e))
#The variable is not greater than zero!!!
Look up the Python error documentation for several use cases.
Conclusion
Errors are inevitable when developing or using applications hence the need to understand how best to manage or handle them in Python programming. The try...exception
is used to catch and handle errors that occur while executing the program. The try
checks for exception and if found the except
throws the error. The try..exception..else..finally are the 4 major keywords in use in Python structure for handling exception. The raise
statement is used to manually raise an exception. Python's exception handling can be used to display proper and readable messages to non-technical users of an application. It makes code readable, clean and easy to debug.
Find this helpful or resourceful? kindly share with others and feel free to use the comment section for questions, answers, and contributions.