Handling Exceptions Using try and except in Python
Course: Python Training
Topic: Handling Exceptions Using try and except
Course Link: Python Training Course at JustAcademy
Demo Link: Register for a Python Course Demo
Website: JustAcademy Official Website
1. Introduction to Exception Handling in Python
Exception handling is an important programming concept that allows developers to manage errors that occur while a program is running. Python provides the try and except statements to detect and handle specific exceptions without immediately terminating the program.
During program execution, errors may occur because of invalid user input, division by zero, missing files, unavailable resources, or incorrect data types. If these exceptions are not handled, they may interrupt normal program execution.
Exception handling allows a program to respond to expected problems, display meaningful error messages, retry operations when appropriate, and continue executing when it is safe to do so.
Example: A Program Without Exception Handling
number1 = 10
number2 = 0
result = number1 / number2
print("Result:", result)
print("Program completed")
Output:
ZeroDivisionError: division by zero
The division operation raises a ZeroDivisionError. The program does not reach the final print statement because the exception remains unhandled.
Example: A Program With Exception Handling
number1 = 10
number2 = 0
try:
result = number1 / number2
print("Result:", result)
except ZeroDivisionError:
print("Error: Division by zero is not allowed.")
print("Program completed")
Output:
Error: Division by zero is not allowed.
Program completed
The exception is handled, and execution continues after the try-except block.
2. Understanding Errors and Exceptions
Before learning exception handling, it is important to understand the difference between syntax errors and runtime exceptions.
2.1 Syntax Errors
A syntax error occurs when Python code violates the language's grammatical rules. Python generally detects these errors before executing the affected code.
if 10 > 5
print("Ten is greater")
Problem: The colon is missing after the condition.
Correct code:
if 10 > 5:
print("Ten is greater")
2.2 Runtime Exceptions
A runtime exception occurs when syntactically valid code encounters a problem during execution.
number = int("hello")
Exception: ValueError, because the string cannot be converted into an integer.
2.3 Logical Errors
A logical error occurs when a program executes but produces an incorrect result because its logic is wrong. Such errors are not automatically handled by try-except unless they also cause an exception.
length = 10
width = 5
area = length + width
print(area)
Output: 15
The intended area of a rectangle is calculated using multiplication, not addition.
Correct code:
area = length * width
print(area)
Output: 50
| Error Type |
Meaning |
Example |
| Syntax error |
Invalid Python syntax |
Missing colon after an if statement |
| Runtime exception |
An operation fails during execution |
Dividing by zero |
| Logical error |
Code executes but produces an incorrect result |
Adding instead of multiplying to calculate area |
3. What Is the try Statement?
The try statement identifies a block of code in which an exception may occur. Python executes the statements inside the block and checks whether an exception is raised.
If an exception occurs, Python stops executing the remaining statements in that try block and looks for a matching exception handler.
Syntax
try:
# Code that may raise an exception
statement1
statement2
except ExceptionType:
# Code to handle the exception
statement3
Example
try:
number = int("25")
print("Number:", number)
except ValueError:
print("Invalid number")
Output:
Number: 25
No exception occurs, so Python skips the except block.
Important Rules for try
- A
try statement must be followed by at least one except or finally clause.
- The statements inside the
try block must be indented.
- Place only the operations that need exception handling inside the block.
- If an exception occurs, the remaining statements in that
try block are skipped.
- An exception raised by a called function can also be handled by the surrounding
try block.
4. What Is the except Statement?
The except statement defines how Python should respond when a matching exception occurs in the associated try block.
It allows developers to provide helpful messages, request new input, select an alternative operation, log errors, or propagate an exception to another part of the application.
Syntax
try:
risky_operation()
except ValueError:
print("The supplied value is invalid.")
Example: Handling Invalid Integer Input
try:
age = int(input("Enter your age: "))
print("Your age is:", age)
except ValueError:
print("Please enter a valid whole number.")
If the user enters twenty, Python raises a ValueError and displays the error message defined in the handler.
If the user enters 20, the conversion succeeds and the age is displayed.
How Python Processes try-except
- Python begins executing the statements in the
try block.
- If no exception occurs, the associated
except blocks are skipped.
- If an exception occurs, the remaining statements in the
try block are skipped.
- Python searches for the first matching
except handler.
- If a matching handler is found, its statements execute.
- Execution continues after the complete
try-except statement.
- If no handler matches, the exception propagates to an outer handler or terminates the current execution if unhandled.
5. Handling Specific Exceptions
Python provides many built-in exception types. Using the correct exception type allows a program to handle a known problem without accidentally hiding unrelated errors.
5.1 ZeroDivisionError
This exception occurs when a number is divided or subjected to certain division operations by zero.
try:
result = 100 / 0
except ZeroDivisionError:
print("Cannot divide by zero.")
Output:
Cannot divide by zero.
5.2 ValueError
A ValueError occurs when an operation receives a value of an appropriate general type but cannot process that value as required.
try:
marks = int("ninety")
except ValueError:
print("Marks must be entered as a number.")
Output:
Marks must be entered as a number.
5.3 TypeError
A TypeError occurs when an operation or function is used with an inappropriate type.
try:
result = "Total: " + 100
except TypeError:
print("Cannot concatenate a string and an integer directly.")
Output:
Cannot concatenate a string and an integer directly.
5.4 IndexError
An IndexError occurs when a sequence is accessed using an index that does not exist.
numbers = [10, 20, 30]
try:
print(numbers[5])
except IndexError:
print("The requested index does not exist.")
Output:
The requested index does not exist.
5.5 KeyError
A KeyError occurs when a dictionary is accessed using a key that is not present.
student = {"name": "Aarav", "marks": 90}
try:
print(student["grade"])
except KeyError:
print("The requested key is unavailable.")
Output:
The requested key is unavailable.
5.6 FileNotFoundError
A FileNotFoundError occurs when an operation attempts to access a file that cannot be found at the specified location.
try:
with open("missing_file.txt", "r", encoding="utf-8") as file:
content = file.read()
except FileNotFoundError:
print("The requested file was not found.")
Output:
The requested file was not found.
Common Python Exceptions
| Exception |
Typical Cause |
ZeroDivisionError |
Dividing by zero |
ValueError |
Invalid value conversion, such as int("hello") |
TypeError |
Performing an operation on incompatible types |
IndexError |
Accessing an invalid sequence index |
KeyError |
Accessing a missing dictionary key |
FileNotFoundError |
Opening a nonexistent file |
PermissionError |
Attempting an operation without the required permission |
AttributeError |
Accessing an unavailable attribute |
NameError |
Using a name that has not been defined |
ImportError |
Failure to import a required name or module |
6. Handling Multiple Exceptions
A single operation may raise different types of exceptions. Python allows multiple except blocks to handle these problems separately.
Example
try:
number1 = int(input("Enter the first number: "))
number2 = int(input("Enter the second number: "))
result = number1 / number2
print("Result:", result)
except ValueError:
print("Please enter valid integers.")
except ZeroDivisionError:
print("The second number cannot be zero.")
Example output when the second number is zero:
Enter the first number: 20
Enter the second number: 0
The second number cannot be zero.
Example output when input is invalid:
Enter the first number: abc
Please enter valid integers.
Only the first matching handler executes for an exception raised in the try block.
Handling Multiple Exception Types in One Block
When multiple exception types require the same response, they can be placed in a tuple.
try:
value = int(input("Enter a number: "))
result = 100 / value
print(result)
except (ValueError, ZeroDivisionError):
print("Enter a valid non-zero integer.")
This approach is useful when different exceptions can be handled with the same message or recovery action.
7. Using except Exception as err
You can capture the exception object in a variable to inspect its message. This is useful for diagnostics and controlled error reporting.
try:
result = 10 / 0
except ZeroDivisionError as err:
print("An error occurred:", err)
Output:
An error occurred: division by zero
For broader error handling, Python supports except Exception as err. However, specific exception handlers are generally preferable because they make the intended recovery behavior clearer.
try:
number = int("hello")
except Exception as err:
print("Operation failed:", err)
print("Exception type:", type(err).__name__)
Output:
Operation failed: invalid literal for int() with base 10: 'hello'
Exception type: ValueError
Best practice: Avoid using a broad handler to silently ignore errors. Unexpected exceptions may indicate programming defects that should be investigated or allowed to propagate.
8. The Difference Between Specific and General Exception Handling
| Feature |
Specific Exception |
General Exception |
| Example |
except ValueError: |
except Exception as err: |
| Coverage |
Handles a particular exception type and its subclasses |
Handles most ordinary application exceptions |
| Clarity |
Clearly describes the expected failure |
Can hide unrelated problems if used carelessly |
| Recommended use |
Expected, known errors |
Boundary-level reporting or logging when justified |
| Recovery |
Can provide a targeted response |
Requires care to avoid inappropriate recovery |
Prefer specific exception types whenever the expected failure is known. Avoid bare except: clauses in ordinary application code because they can also catch exceptions such as KeyboardInterrupt and SystemExit.
9. Using try-except with User Input
User input is a common source of exceptions because the entered data may not match the expected format. Exception handling helps applications validate input and communicate clearly with users.
Example: Accepting a Valid Integer
try:
age = int(input("Enter your age: "))
if age < 0:
print("Age cannot be negative.")
else:
print("Your age is:", age)
except ValueError:
print("Invalid input. Enter a whole number.")
This example handles invalid integer conversion and separately checks whether the entered age is within an acceptable range.
Example: Repeatedly Requesting Valid Input
while True:
try:
age = int(input("Enter your age: "))
if age < 0:
print("Age cannot be negative.")
continue
print("Accepted age:", age)
break
except ValueError:
print("Invalid input. Please enter a whole number.")
The loop continues until a non-negative integer is entered. The continue statement requests another input when the age is negative, while break ends the loop after valid input.
10. Using try-except with Functions
Exceptions can occur inside functions called from a try block. A surrounding handler can catch an exception raised by a function, provided the exception propagates back to that handler.
def divide_numbers(a, b):
return a / b
try:
result = divide_numbers(20, 0)
print("Result:", result)
except ZeroDivisionError:
print("The division operation failed.")
Output:
The division operation failed.
Here, divide_numbers() raises a ZeroDivisionError, which is handled by the surrounding block.
Handling Exceptions Inside a Function
def convert_to_integer(value):
try:
return int(value)
except ValueError:
print("Conversion failed.")
return None
result = convert_to_integer("hello")
print(result)
Output:
Conversion failed.
None
This function handles the expected conversion failure internally and returns None to indicate that conversion did not succeed. In production applications, choose a return value or error-handling strategy that clearly distinguishes failure from valid data.
11. Using try-except with File Operations
File operations may fail because a file is missing, permissions are insufficient, a disk or device is unavailable, or another operating-system error occurs. Handling expected file exceptions helps applications respond gracefully.
Example: Reading a File
try:
with open("notes.txt", "r", encoding="utf-8") as file:
content = file.read()
print(content)
except FileNotFoundError:
print("The file does not exist.")
except PermissionError:
print("You do not have permission to read this file.")
except OSError as err:
print("A file system error occurred:", err)
The example handles missing files and permission problems separately, then provides a fallback for other operating-system errors.
Why Use with open()?
The with statement manages the file's lifecycle and ensures it is closed when the block exits, including when an exception occurs during reading. This is generally safer than manually opening and closing files.
12. Understanding the else Clause
The optional else clause runs only when the try block completes without raising an exception. It is useful for separating successful operations from exception-handling logic.
Syntax
try:
# Risky operation
statement
except SomeException:
# Handle the failure
statement
else:
# Runs only when try succeeds
statement
Example
try:
number = int(input("Enter a number: "))
except ValueError:
print("Invalid number.")
else:
print("Conversion successful.")
print("Number:", number)
Example output for valid input:
Enter a number: 25
Conversion successful.
Number: 25
Example output for invalid input:
Enter a number: abc
Invalid number.
Using else keeps statements that depend on successful execution outside the protected try block. This reduces the risk of accidentally catching exceptions raised by unrelated code.
13. Understanding the finally Clause
The finally clause executes when the try statement is leaving, whether or not an exception occurred. It is commonly used for cleanup operations.
Syntax
try:
# Operation that may fail
statement
except SomeException:
# Handle the error
statement
finally:
# Cleanup operation
statement
Example
try:
print("Starting operation")
result = 10 / 0
except ZeroDivisionError:
print("Division error handled.")
finally:
print("Cleanup completed.")
Output:
Starting operation
Division error handled.
Cleanup completed.
The finally block is executed even though the division operation fails.
Common Uses of finally
- Releasing resources.
- Closing connections when manual cleanup is necessary.
- Restoring application state.
- Performing cleanup that should occur whether an operation succeeds or fails.
For files and many other resource types, context managers such as with are generally the preferred cleanup mechanism.
14. Understanding the raise Statement
The raise statement allows a developer to deliberately raise an exception when a condition violates the rules of an application.
Example: Raising a ValueError
def set_age(age):
if age < 0:
raise ValueError("Age cannot be negative.")
return age
try:
print(set_age(-5))
except ValueError as err:
print("Validation error:", err)
Output:
Validation error: Age cannot be negative.
The function explicitly rejects a negative age by raising a ValueError. The calling code handles that exception.
Re-raising an Exception
Sometimes, code must log or inspect an exception before allowing it to propagate. Use raise without an argument inside an exception handler to re-raise the current exception.
try:
number = int("abc")
except ValueError:
print("Conversion failed; passing the error to the caller.")
raise
The error is reported and then raised again. If no outer handler catches it, execution terminates with the exception traceback.
15. Common Mistakes in Exception Handling
| Mistake |
Why It Is a Problem |
Better Approach |
Using a bare except: |
Can catch interruptions and exit signals unintentionally. |
Catch specific exceptions or use Exception when justified. |
Using an overly broad try block |
May catch failures from unrelated operations. |
Protect only the statements that may raise expected exceptions. |
| Silently ignoring exceptions |
Hides failures and makes debugging difficult. |
Log the problem or provide an appropriate recovery action. |
| Using the wrong exception type |
The expected failure is not handled. |
Identify the exception type and handle it explicitly. |
| Placing all code inside one handler |
Unrelated errors may be mistaken for the same failure. |
Separate operations and use targeted handlers. |
| Displaying technical details to every user |
May confuse users or expose sensitive information. |
Show a clear message and log suitable diagnostic details securely. |
| Using exceptions for normal control flow unnecessarily |
Makes simple logic harder to understand. |
Use conditions for expected checks when practical. |
16. Best Practices for Exception Handling
- Handle only exceptions that you understand and can respond to meaningfully.
- Prefer specific exception types such as
ValueError, ZeroDivisionError, and FileNotFoundError.
- Keep the protected code inside the
try block as small as practical.
- Use
as err when the exception message is needed for diagnostics.
- Use
else for operations that should run only when the try block succeeds.
- Use
finally for necessary cleanup, or use context managers when available.
- Do not expose passwords, tokens, personal data, or other sensitive information in error messages and logs.
- Avoid empty exception handlers that silently suppress failures.
- Use
raise when an exception cannot be handled appropriately at the current level.
- Test both successful and failing execution paths.
- Provide messages that explain how the user can correct an input problem.
- Do not use exception handling as a substitute for proper validation and program design.
17. Practical Project: Simple Calculator with Exception Handling
Build a calculator that accepts two numbers and an operator. The program handles invalid numeric input, unsupported operators, and division by zero.
def calculator():
try:
first = float(input("Enter the first number: "))
operator = input("Enter an operator (+, -, *, /): ")
second = float(input("Enter the second number: "))
if operator == "+":
result = first + second
elif operator == "-":
result = first - second
elif operator == "*":
result = first * second
elif operator == "/":
result = first / second
else:
raise ValueError("Unsupported operator.")
except ValueError as err:
print("Input or operation error:", err)
except ZeroDivisionError:
print("Error: Cannot divide by zero.")
else:
print("Result:", result)
calculator()
Example Output: Successful Calculation
Enter the first number: 20
Enter an operator (+, -, *, /): +
Enter the second number: 10
Result: 30.0
Example Output: Division by Zero
Enter the first number: 20
Enter an operator (+, -, *, /): /
Enter the second number: 0
Error: Cannot divide by zero.
Example Output: Invalid Number
Enter the first number: abc
Input or operation error: could not convert string to float: 'abc'
This project demonstrates how exception handling can improve the reliability and usability of a small application. In larger applications, you may choose to validate operators separately and use custom exceptions to distinguish invalid input from unsupported operations.
18. Practice Exercises
Exercise 1: Division Program
Write a program that accepts two integers and divides the first by the second. Handle ZeroDivisionError and ValueError separately.
Exercise 2: Age Validation
Accept a user's age as input. Handle invalid integer input and raise a ValueError if the age is negative.
Exercise 3: List Access
Create a list of five numbers and ask the user to enter an index. Handle IndexError when the index is outside the list's valid range.
Exercise 4: Dictionary Lookup
Create a dictionary containing student names and marks. Ask for a student name and handle a missing key using KeyError, or use the dictionary's get() method if a default result is appropriate.
Exercise 5: File Reading
Write a program that reads a text file and handles FileNotFoundError and other relevant OSError exceptions.
Exercise 6: Multiple Exception Handlers
Write a program that converts user input to an integer and calculates a result. Handle invalid input and division by zero using separate except blocks.
Exercise 7: try-except-else-finally
Create a program that accepts a number, displays a success message when conversion works, handles invalid input, and always prints a final cleanup message.
Exercise 8: Custom Validation
Create a function that accepts a product price. Raise a ValueError for a negative price and handle it in the calling code.
19. Interview Questions and Answers
Q1. What is exception handling in Python?
Exception handling is a mechanism for responding to runtime errors using constructs such as try, except, else, and finally.
Q2. What is the purpose of the try block?
The try block contains statements that may raise exceptions and need to be monitored for expected failures.
Q3. What is the purpose of the except block?
The except block handles an exception when its specified type matches an exception raised in the corresponding try block.
Q4. Can a try block have multiple except blocks?
Yes. Multiple handlers can handle different exception types separately. Only the first matching handler runs for a given exception.
Q5. What is the difference between ValueError and TypeError?
ValueError generally means the value is unsuitable for an operation, while TypeError means the object type is inappropriate for that operation.
Q6. What happens if an exception is not handled?
The exception propagates to an outer handler. If no handler catches it, the current execution terminates with an error traceback.
Q7. What is the purpose of the else block?
The else block executes only when the associated try block completes without raising an exception.
Q8. What is the purpose of finally?
The finally block performs cleanup when the try statement exits, whether an exception occurred or not.
Q9. What does except Exception as err mean?
It catches most ordinary application exceptions derived from Exception and assigns the exception object to err.
Q10. How do you raise an exception manually?
Use the raise statement, for example raise ValueError("Invalid input").
Q11. Why should bare except clauses generally be avoided?
They may catch interruptions and termination signals that the program should normally allow to propagate. Specific handlers are clearer and safer.
Q12. Can exceptions raised inside functions be caught outside those functions?
Yes. If a function raises an exception that is not handled inside it, the exception can propagate to a surrounding try-except block.
Q13. Does try-except handle syntax errors in the same code block?
Not generally. Syntax errors detected while parsing a module prevent that module from executing normally. Runtime exceptions are the primary purpose of ordinary try-except handling.
Q14. What is the difference between handling and suppressing an exception?
Handling means taking an appropriate action in response to the failure. Suppressing means preventing the exception from propagating, potentially without addressing the underlying problem.
20. Quick Revision Checklist
- Understand the difference between syntax errors, runtime exceptions, and logical errors.
- Know the basic syntax of
try and except.
- Recognize common exceptions such as
ValueError, TypeError, ZeroDivisionError, and IndexError.
- Use multiple
except blocks for different failure types.
- Understand how
except Exception as err captures an exception object.
- Know when to use
else and finally.
- Use
raise to report invalid conditions or re-raise an exception.
- Handle file operations and user input carefully.
- Avoid broad handlers that hide unexpected programming errors.
- Practice testing both successful and unsuccessful execution paths.
21. Conclusion
Handling exceptions using try and except is an essential Python programming skill. It allows developers to manage expected runtime failures, provide helpful error messages, validate user input, and build more reliable applications.
By learning how to handle specific exceptions, capture exception messages, and use the optional else and finally clauses, developers can create programs that respond to errors in a controlled and understandable way.
Regular practice with input validation, file operations, calculations, and function calls will help you apply exception handling effectively in real-world Python projects.
Learn Python with JustAcademy
Explore Python concepts, practice programming examples, and strengthen your skills through structured learning.
Explore the Python Training Course
Register for a Course Demo
Visit the JustAcademy Website