Error Handling in SocialMapper¶
SocialMapper provides a comprehensive error handling system designed to give clear, actionable feedback to users when things go wrong.
Overview¶
The error handling system in SocialMapper follows these principles:
- Clear Error Messages: Every error provides a human-readable explanation
- Actionable Suggestions: Errors include suggestions for how to fix the problem
- Rich Context: Errors capture relevant context for debugging
- Error Chaining: Original causes are preserved through the error chain
- Type Safety: Custom exception hierarchy for different error categories
Exception Hierarchy¶
SocialMapperError (base)
├── ConfigurationError
│ ├── MissingAPIKeyError
│ └── InvalidConfigurationError
├── ValidationError
│ ├── InvalidLocationError
│ ├── InvalidCensusVariableError
│ └── InvalidTravelTimeError
├── DataProcessingError
│ ├── NoDataFoundError
│ └── InsufficientDataError
├── ExternalAPIError
│ ├── CensusAPIError
│ ├── OSMAPIError
│ └── GeocodingError
├── FileSystemError
│ ├── FileNotFoundError
│ └── PermissionError
├── AnalysisError
│ ├── IsochroneGenerationError
│ └── NetworkAnalysisError
└── VisualizationError
└── MapGenerationError
Common Errors and Solutions¶
1. Invalid Location Format¶
Error: InvalidLocationError
Example:
# Wrong
client.analyze(location="San Francisco")
# Correct
client.analyze(location="San Francisco, CA")
Suggestions: - Use format: 'City, State' (e.g., 'San Francisco, CA') - Or use format: 'County, State' (e.g., 'Wake County, North Carolina')
2. Missing Census API Key¶
Error: MissingAPIKeyError
Solution:
1. Get a free API key from https://api.census.gov/data/key_signup.html
2. Set as environment variable: export CENSUS_API_KEY='your-key-here'
3. Or pass directly: .with_census_api_key('your-key')
3. No POIs Found¶
Error: NoDataFoundError
Common Causes: - POI type doesn't exist in the area - Location name is misspelled - Search area is too small
Solutions: - Try different POI types: 'school', 'hospital', 'park' - Use a larger area (county instead of city) - Verify spelling of location names
4. Invalid Travel Time¶
Error: InvalidTravelTimeError
Valid Range: 1-120 minutes
Example:
5. Network/API Errors¶
Error: OSMAPIError
, CensusAPIError
Common Solutions: - Check internet connection - Wait and retry (rate limiting) - Verify API credentials - Check service status
Using Error Handling in Tutorials¶
The tutorial_error_handler
provides user-friendly error messages for tutorials:
from socialmapper import tutorial_error_handler
with tutorial_error_handler("My Tutorial"):
# Tutorial code here
result = run_analysis()
This will: - Catch common errors - Provide helpful suggestions - Format errors nicely for learners - Exit gracefully with appropriate messages
Error Context and Debugging¶
Each error includes rich context:
try:
# Some operation
except SocialMapperError as e:
print(f"Error: {e}")
print(f"Category: {e.context.category}")
print(f"Severity: {e.context.severity}")
print(f"Operation: {e.context.operation}")
print(f"Suggestions: {e.context.suggestions}")
print(f"Details: {e.context.details}")
Best Practices¶
1. Use Specific Exceptions¶
2. Add Context¶
# Good
raise DataProcessingError(
"Failed to process census data",
geoids=geoids,
variable=variable
).with_operation("census_integration")
# Avoid
raise Exception("Processing failed")
3. Chain Exceptions¶
try:
result = external_api_call()
except RequestException as e:
raise OSMAPIError(
"Failed to query OpenStreetMap",
cause=e, # Preserves original error
query=query
)
4. Provide Suggestions¶
error = NoDataFoundError("libraries", location="Rural Town")
error.add_suggestion("Try searching for a larger area")
error.add_suggestion("Check if libraries exist in this region")
raise error
Error Recovery Patterns¶
1. Retry on Transient Errors¶
from socialmapper.util.error_handling import with_retries
@with_retries(max_attempts=3, exceptions=(OSMAPIError,))
def fetch_pois():
return query_overpass(query)
2. Fallback Values¶
from socialmapper.util.error_handling import with_fallback
@with_fallback([], NoDataFoundError)
def get_census_data():
return fetch_census_data()
3. Batch Error Collection¶
from socialmapper.util.error_handling import ErrorCollector
collector = ErrorCollector()
for location in locations:
with collector.collect(location):
process_location(location)
if collector.has_errors:
print(f"Failed: {collector.error_count} locations")
API Error Handling¶
The modern API uses the Result pattern:
result = client.analyze(location="San Francisco, CA",
poi_type="amenity",
poi_name="library")
match result:
case Ok(analysis):
print(f"Found {analysis.poi_count} POIs")
case Err(error):
print(f"Error: {error.message}")
if error.type == ErrorType.VALIDATION:
print("Check your input parameters")
Logging Integration¶
Errors are automatically logged with appropriate levels:
from socialmapper.util.error_handling import log_error
try:
risky_operation()
except SocialMapperError as e:
log_error(e, ErrorSeverity.ERROR)
Testing Error Conditions¶
import pytest
from socialmapper import InvalidLocationError
def test_location_validation():
with pytest.raises(InvalidLocationError) as exc_info:
validate_location("BadLocation")
error = exc_info.value
assert "City, State" in error.context.suggestions[0]
Migration from Old Error Handling¶
If you're updating old code: