Error Handling Best Practices¶
Exception Hierarchy¶
All exceptions inherit from PortfolioManagementError:
DataError- Data loading, validation, matchingPortfolioConstructionError- Portfolio construction, strategies, constraintsBacktestError- Backtesting, performance calculationConfigurationError- Configuration validation
Raising Exceptions¶
Always use custom exceptions with context:
# Good
from portfolio_management.core.exceptions import DataLoadError
def load_returns(path: Path) -> pd.DataFrame:
if not path.exists():
raise DataLoadError(path, "File does not exist")
# ...
Error Messages¶
Include actionable context:
- File paths
- Asset symbols
- Invalid values
- Expected values
- Suggestions for fixing
# Good error message
raise StrategyError(
"mean_variance",
"Optimization failed: covariance matrix is singular. "
"Try removing assets with zero variance."
)
# Bad error message
raise ValueError("Optimization failed")
Error Recovery¶
Use retry patterns for transient errors:
from portfolio_management.core.error_handling import retry_on_error
result = retry_on_error(
lambda: load_data(path),
max_attempts=3,
exceptions=(IOError,),
)
Validation Patterns¶
Validate early and provide clear feedback: