Error Handling
Introduction to Errors
In Python, there are (at least) two kinds of errors: syntax errors and exceptions.
Syntax Errors
A syntax error, also known as a parsing error, is when your code does not follow rules for writing Python code. Python interpreter shows an error message when it encounters a syntax error.
The code below has a syntax error because it breaks the Python rule that requires a : to follow the condition of an if statement.
| → | |
Some Python editors (e.g., repl.it) flag syntax errors even before you run the code.
Note how replt.it Python editor points out the syntax error using a red ❌ in the of the editor.
Handling Exceptions
Errors detected during execution are called exceptions. Even if the code is syntactically correct, it may cause an error during execution. Python different types of exceptions; the type of exception used depends on the tye nature of the error.
The code below raises an exception when it attempts to divide a number by 0. The type of the exception raised is ZeroDivisionError, as mentioned in the last line of the error message.
| → | |
It is not desirable for programs to 'crash' every time an exception occurs. You can use the try-except syntax to specify how to handle exceptions. The try clause contains the code that can possibly raise an exception while the except clause contains the code that handles the exception.
The code below specifies what to do if the ZeroDivisionError is raised, thereby avoiding a program crash in such an event.
| → | |
When the code in a try clause raises an error, the program execution immediately moves to the code in the except clause, provided the exception that happened matches the exception the except clause is supposed to . After running the code in the except clause, the execution continues as normal.
If the exception does not match the except clause, the program crashes.
The code below crashes because the actual exception (caused by passing a string when an floating point number is expected) does not match the specified exception ZeroDivisionError.
| → | |
You can specify multiple except clauses, one for each type of exception expected.
The code below handles two types of exceptions: ZeroDivisionError and ValueError.
The ValueError is raised when the string abc is being converted to a float using float(divisor).
| → | |
It is possible to specify multiple exception types in one except clause.
The code below handles both ZeroDivisionError and ValueError in the same except clause.
| → | |
IndexError is an exception thrown when you try to access an index (e.g., when reading values form a list) that does not exist.
In this example, calling get_head on an empty list causes an IndexError.
| → | |
It is also possible to use except Exception to catch any kind of exception. However, that practice is discouraged.
The code below handles both ZeroDivisionError and ValueError and any other exception in the same except clause.
| → | |
📎 Resources:
Raising Exceptions
You can raise an exception yourself to indicate an error.
The get_body(items) function below raises an exception when it receives a list that has fewer than 3 items. That exception is 'caught' and handled by the hide_ends(items) function.
Also note how an except clause can assign a name to the exception using as temporary_name (as done by except ValueError as e:) so that the exception object can be referenced later (as done in print('Cannot hide ends', str(e)))
| → | |
It is also possible to catch an exception, do something, and then raise it again so that the exception propagates to the caller.
The code hide_ends2(items) function below catches the ValueError exception, prints an error message, and raises it again so that the code that called the function can catch the exception again. Also note how the line hide_ends2([0, 1, 2, 3, 4]) is never executed due to the exception raised by the line just above it.
| → | |
Here are some commonly used built-in exceptions (full list) you can raise/handle in your code:
IndexError: Indicates an index of a sequence (e.g., a list) is out of range.RuntimeError: Indicates an error that does not fall under any other category.ValueError: Indicates when a function gets argument of correct type but improper value.ZeroDivisionError: Indicates an attempt to divide by zero.
It is also possible to define your own user-defined exceptions but that requires more advanced programming techniques. It will be covered elsewhere.
