
Errors are an inevitable part of programming. A missing file, invalid user input, or a network issue can cause a Python program to fail unexpectedly. Instead of allowing your application to crash, Python provides a powerful exception handling mechanism that lets you detect errors, respond appropriately, and keep your program running whenever possible.
Python Exception Handling improves the reliability, maintainability, and user experience of your applications by separating normal program logic from error-handling logic.
In this guide, you’ll learn how to handle exceptions using try, except, else, and finally, create custom exceptions, and follow industry best practices.
Definition
An exception is an error that occurs while a program is running.
When an exception occurs, Python interrupts the normal flow of the program and generates an error message.
Example exceptions include:
- Division by zero
- File not found
- Invalid user input
- Index out of range
- Key not found in a dictionary
Advantages of Exception Handling
- Improved Code Readability: It allows errors to be handled cleanly.
- Program Continuity: Exceptions enable programs to continue running even after encountering an error.
- Error Logging: Helps diagnose the issue by capturing specific error details.
- Separation of Error Handling Logic: Keeps normal code separate from error-handling logic.
- Graceful Termination: Programs can terminate gracefully instead of crashing abruptly.
Two types of errors in a programming language
- Syntax error
- Runtime error
Syntax Error:
Syntax errors occurs when the code breaks or violates the rules or structure of the programming language. These errors are detected before the program runs, during the compilation or interpretation phase. The program cannot execute until the syntax error is fixed.
Example:
print("Hello World" # Missing closing parenthesis
Explanation: In the above example, the closing parenthesis is missing, causing a syntax error. The program will not run and will raise an error like:
SyntaxError: unexpected EOF while parsing
Note: A programmer must correct all syntax errors before executing the program.
Runtime Errors:
Runtime errors occurs during the execution of the program. These errors happen after the program has started executing and typically arise due to unexpected operations (e.g., division by zero, invalid operations on data types, programmer logic, memory problems, or end-user input… ).
Example:
x = 10 / 0 # Division by zero
Explanation: Here, the program will start executing but will break at the point where the division done by zero occurs. This will result in a runtime error like:
ZeroDivisionError: division by zero
Note: Exception Handling concept applicable for Runtime Errors but not for syntax errors.
Exception hierarchy diagram

Most commonly encounter error are
| Error Type | Description | Example |
| SyntaxError | Occurs when the Python parser detects a syntax error. | x = 10 print(x) # Missing a colon in function or if statement |
| IndentationError | Raised when there is incorrect indentation in the code. | def my_function(): print(“Hello”) # Expected indentation block |
| TypeError | Raised when an operation or function is applied to an object of inappropriate type. | result = “2” + 2 # Trying to add a string and an integer |
| ValueError | Raised when a function receives an argument of the right type but inappropriate value. | int(“abc”) # Converting a string to integer when it’s not a valid number |
| NameError | Raised when a local or global name is not found. | print(age) # Trying to use a variable that hasn’t been defined |
| ZeroDivisionError | Raised when attempting to divide by zero. | result = 10 / 0 # Division by zero error |
| IndexError | Raised when trying to access an index that is out of range in a sequence (e.g., list, tuple). | my_list = [1, 2, 3] print(my_list[5]) # Accessing an index that doesn’t exist |
| KeyError | Raised when trying to access a dictionary with a key that doesn’t exist. | my_dict = {“name”: “Alex”} print(my_dict[“age”]) # Accessing a nonexistent key |
| AttributeError | Raised when an invalid attribute reference or assignment occurs. | x = 5 x.append(10) # Trying to use a list method on an integer |
| ModuleNotFoundError | Raised when attempting to import a module that cannot be found. | import nonexistent_module # Trying to import a module that doesn’t exist |
| FileNotFoundError | Raised when trying to open a file that does not exist. | with open(“nonexistent_file.txt”, “r”) as file: data = file.read() # Trying to read a file that doesn’t exist |
| OverflowError | Raised when the result of an arithmetic operation is too large to be represented. | import math math.exp(1000) # Exceeding the maximum value representable by a float |
| ImportError | Raised when an import statement fails to find the module definition or when an imported object cannot be retrieved. | from math import non_existent_function # Trying to import a non-existent function from a module |
Types of Exceptions with Syntax:
1. try-except block:
try:
# code that may raise an exception
except <ExceptionType>:
# code to execute if the exception is raised
2. try with multiple except blocks:
try:
# code that may raise an exception
except <ExceptionType>: # ZeroDivisionError
# code to handle the exception
except <ExceptionType>: #ValueError
# code to handle the exception
else:
# code to execute if no exception was raised
3. Single except block can handle multiple exceptions:
try:
# code that may raise an exception
except (Exception1,Exception2,exception3,..):
# code that may raise an exception
# (OR)
except (Exception1,Exception2,exception3,..) as msg:
# code that may raise an exception
Note: The following are different possible variations of except blocks.
- except ZeroDivisionError:
- except ZeroDivisionError as msg:
- except (ZeroDivisionError, ValueError) :
- except (ZeroDivisionError, ValueError) as msg:
- except :
4. try-except-else block:
try:
# code that may raise an exception
except <ExceptionType>:
# code to handle the exception
else:
# code to execute if no exception was raised
5. try-except-finally block:
try:
# code that may raise an exception
except <ExceptionType>:
# code to handle the exception
finally:
# code that will always execute, regardless of exceptions
6. Raise exception:
raise <ExceptionType>('error message')
7. Custom Exceptions:
class CustomError(Exception):
pass
Examples:
Basic try-except:
try:
x = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero.")
try with multiple except blocks:
try:
x=int(input("Enter First Number: "))
y=int(input("Enter Second Number: "))
print(x/y)
except ZeroDivisionError:
print("Can't Divide with Zero")
except ValueError:
print("please provide int value only")
Single except block can handle multiple exceptions:
try:
x=int(input("Enter First Number: "))
y=int(input("Enter Second Number: "))
print(x/y)
except (ZeroDivisionError, ValueError) as z:
print("Please Provide valid numbers only and problem is: ", z)
try-except-else-finally:
try:
result = 10 / 5
except ZeroDivisionError:
print("Division by zero!")
else:
print("Result:", result)
finally:
print("This block always executes.")
Raising a Custom Exception:
class InvalidAgeError(Exception):
def __init__(self, age):
self.age = age
def validate_age(age):
if age < 18:
raise InvalidAgeError("Age is less than 18.")
try:
validate_age(15)
except InvalidAgeError as e:
print(e)
Frequently Asked Questions
Python Exception Handling is a mechanism that allows programs to detect, manage, and recover from runtime errors without crashing.
A syntax error occurs before the program runs, while an exception occurs during program execution and can often be handled using try-except.
The finally block always executes and is commonly used to close files, release resources, or perform cleanup operations.
Create custom exceptions when your application needs meaningful, domain-specific error types that built-in exceptions do not adequately describe.
Conclusion
Python Exception Handling is an essential skill for building reliable applications. By using try, except, else, and finally effectively, you can manage runtime errors gracefully while keeping your code clean and maintainable. Following best practices such as catching specific exceptions, keeping try blocks small, and avoiding silent failures will help you create robust Python programs that are easier to debug and maintain.
Knowledge Check
Related Article No.4
Check out our Trending Courses Demo Playlist
| Data Analytics with Power Bi and Fabric |
| Could Data Engineer |
| Data Analytics With Power Bi Fabic |
| AWS Data Engineering with Snowflake |
| Azure Data Engineering |
| Azure & Fabric for Power bi |
| Full Stack Power Bi |
Kick Start Your Career With Our Data Job
Social Media channels
► KSR Datavizon Website :- https://www.datavizon.com
► KSR Datavizon LinkedIn :- https://www.linkedin.com/company/datavizon/
► KSR Datavizon You tube :- https://www.youtube.com/c/KSRDatavizon
► KSR Datavizon Twitter :- https://twitter.com/ksrdatavizo


Most Commented