Error Handling Techniques
Assertion vs Exception Handling
Comparison of Error Management Strategies
Strategy |
Purpose |
Execution |
Recommended Use |
Assertions |
Internal logic checks |
Debugging |
Development phase |
Exceptions |
External error handling |
Runtime error management |
Production environments |
Combining Assertions with Try-Except Blocks
def process_data(data):
try:
## Assertions for internal validation
assert isinstance(data, list), "Input must be a list"
assert len(data) > 0, "List cannot be empty"
## Process data
result = [x * 2 for x in data]
return result
except AssertionError as ae:
## Custom error handling
print(f"Validation Error: {ae}")
return None
except Exception as e:
## Fallback error handling
print(f"Unexpected error: {e}")
return None
## Usage examples
print(process_data([1, 2, 3])) ## Valid input
print(process_data([])) ## Handles assertion error
Error Handling Workflow
graph TD
A[Input Data] --> B{Assertion Checks}
B -->|Pass| C{Try Block}
B -->|Fail| D[Raise AssertionError]
C -->|Success| E[Return Result]
C -->|Fail| F[Catch Exception]
D --> G[Catch AssertionError]
F --> H[Handle Exception]
G --> H
Advanced Error Handling Patterns
Logging Assertions
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def validate_user_input(username, age):
try:
assert isinstance(username, str), "Username must be a string"
assert isinstance(age, int), "Age must be an integer"
assert 0 < age < 120, "Invalid age range"
logger.info(f"User {username} validated successfully")
return True
except AssertionError as ae:
logger.error(f"Validation failed: {ae}")
return False
Conditional Assertions
Dynamic Assertion Enabling
import sys
def debug_assert(condition, message):
## Only check assertions when not in optimized mode
if not sys.flags.optimize:
assert condition, message
## Example usage
def calculate_average(numbers):
debug_assert(len(numbers) > 0, "Cannot calculate average of empty list")
return sum(numbers) / len(numbers)
Error Handling Best Practices
- Use assertions for internal logic checks
- Implement comprehensive exception handling
- Log errors for debugging purposes
- Provide meaningful error messages
- Handle specific exception types
Assertion Overhead
import timeit
## Comparing performance with and without assertions
def with_assertions(data):
assert len(data) > 0
return sum(data)
def without_assertions(data):
return sum(data)
## Benchmark
print(timeit.timeit('with_assertions([1,2,3])', globals=globals(), number=100000))
print(timeit.timeit('without_assertions([1,2,3])', globals=globals(), number=100000))
LabEx Recommendation
LabEx emphasizes the importance of a balanced approach to error handling, combining assertions for development-time checks with robust exception handling for production environments.
Conclusion
Effective error handling requires a strategic approach that leverages both assertions and exception handling techniques to create reliable and maintainable Python code.