Initial commit: sales analysis template
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
276
.cursor/rules/error_handling.md
Normal file
276
.cursor/rules/error_handling.md
Normal file
@@ -0,0 +1,276 @@
|
||||
# Error Handling Best Practices
|
||||
|
||||
This guide defines how to handle errors in a way that's helpful for both users and AI assistants.
|
||||
|
||||
## Error Message Structure
|
||||
|
||||
### Required Elements
|
||||
|
||||
Every error message should include:
|
||||
1. **What went wrong** - Specific error description
|
||||
2. **Where it occurred** - File/function context
|
||||
3. **Why it happened** - Root cause explanation
|
||||
4. **How to fix** - Actionable steps
|
||||
5. **Reference** - Link to relevant documentation
|
||||
|
||||
### Template
|
||||
|
||||
```python
|
||||
raise ErrorType(
|
||||
f"[What] - [Specific description]\n"
|
||||
f"\n"
|
||||
f"Context: [Where/When this occurred]\n"
|
||||
f"Reason: [Why this happened]\n"
|
||||
f"\n"
|
||||
f"Solution:\n"
|
||||
f"1. [Step 1]\n"
|
||||
f"2. [Step 2]\n"
|
||||
f"\n"
|
||||
f"For more help, see: [Documentation reference]"
|
||||
)
|
||||
```
|
||||
|
||||
## Common Error Patterns
|
||||
|
||||
### Data Loading Errors
|
||||
|
||||
```python
|
||||
# Good: Comprehensive error message
|
||||
if REVENUE_COLUMN not in df.columns:
|
||||
available_cols = list(df.columns)[:10] # Show first 10
|
||||
raise ValueError(
|
||||
f"Required column '{REVENUE_COLUMN}' not found in data.\n"
|
||||
f"\n"
|
||||
f"Context: Loading data from {filepath}\n"
|
||||
f"Available columns: {available_cols}\n"
|
||||
f"\n"
|
||||
f"Solution:\n"
|
||||
f"1. Check your CSV file column names\n"
|
||||
f"2. Update REVENUE_COLUMN in config.py to match your data\n"
|
||||
f"3. Run: python config_validator.py to validate configuration\n"
|
||||
f"\n"
|
||||
f"For more help, see: .cursor/rules/data_loading.md"
|
||||
)
|
||||
|
||||
# Bad: Vague error
|
||||
if REVENUE_COLUMN not in df.columns:
|
||||
raise ValueError("Column not found")
|
||||
```
|
||||
|
||||
### Configuration Errors
|
||||
|
||||
```python
|
||||
# Good: Actionable error
|
||||
if LTM_ENABLED and (LTM_START is None or LTM_END is None):
|
||||
raise ValueError(
|
||||
f"LTM configuration error: LTM_ENABLED is True but LTM period is not set.\n"
|
||||
f"\n"
|
||||
f"Context: Configuration in config.py\n"
|
||||
f"Current values: LTM_ENABLED={LTM_ENABLED}, LTM_START={LTM_START}, LTM_END={LTM_END}\n"
|
||||
f"\n"
|
||||
f"Solution:\n"
|
||||
f"1. Set LTM_START_MONTH, LTM_START_YEAR, LTM_END_MONTH, LTM_END_YEAR in config.py\n"
|
||||
f"2. Or set LTM_ENABLED = False if you don't need LTM\n"
|
||||
f"3. Run: python config_validator.py to check configuration\n"
|
||||
f"\n"
|
||||
f"For more help, see: .cursor/rules/ltm_methodology.md"
|
||||
)
|
||||
```
|
||||
|
||||
### Data Quality Errors
|
||||
|
||||
```python
|
||||
# Good: Helpful data quality error
|
||||
if date_coverage < 0.5: # Less than 50% coverage
|
||||
raise ValueError(
|
||||
f"Data quality issue: Only {date_coverage:.1%} of rows have valid dates.\n"
|
||||
f"\n"
|
||||
f"Context: Date parsing in data_loader.py\n"
|
||||
f"Rows with dates: {date_count:,} / {total_rows:,}\n"
|
||||
f"\n"
|
||||
f"Solution:\n"
|
||||
f"1. Check date format in your CSV file\n"
|
||||
f"2. Add fallback date columns to DATE_FALLBACK_COLUMNS in config.py\n"
|
||||
f"3. Ensure at least one date column (Month, Year) exists\n"
|
||||
f"4. Run: python data_quality.py to analyze data quality\n"
|
||||
f"\n"
|
||||
f"For more help, see: .cursor/rules/data_loading.md"
|
||||
)
|
||||
```
|
||||
|
||||
## Error Handling Patterns
|
||||
|
||||
### Try-Except with Context
|
||||
|
||||
```python
|
||||
# Good: Provides context and recovery options
|
||||
try:
|
||||
df = load_sales_data(get_data_path())
|
||||
except FileNotFoundError as e:
|
||||
error_msg = (
|
||||
f"Data file not found: {e}\n"
|
||||
f"\n"
|
||||
f"Context: Attempting to load data for analysis\n"
|
||||
f"Expected file: {get_data_path()}\n"
|
||||
f"\n"
|
||||
f"Solution:\n"
|
||||
f"1. Check that your CSV file exists at the expected location\n"
|
||||
f"2. Update DATA_FILE in config.py with correct filename\n"
|
||||
f"3. Or update DATA_DIR if file is in a subdirectory\n"
|
||||
f"4. Run: python setup_wizard.py to reconfigure\n"
|
||||
f"\n"
|
||||
f"For more help, see: .cursor/rules/common_errors.md"
|
||||
)
|
||||
raise FileNotFoundError(error_msg) from e
|
||||
```
|
||||
|
||||
### Validation with Helpful Messages
|
||||
|
||||
```python
|
||||
# Good: Validates and provides specific guidance
|
||||
def validate_data_structure(df: pd.DataFrame) -> Tuple[bool, str]:
|
||||
"""
|
||||
Validate DataFrame has required structure
|
||||
|
||||
Returns:
|
||||
Tuple[bool, str]: (is_valid, error_message)
|
||||
If is_valid is False, error_message contains actionable guidance
|
||||
"""
|
||||
errors = []
|
||||
|
||||
if REVENUE_COLUMN not in df.columns:
|
||||
errors.append(
|
||||
f"Missing required column '{REVENUE_COLUMN}'. "
|
||||
f"Update REVENUE_COLUMN in config.py to match your data."
|
||||
)
|
||||
|
||||
if DATE_COLUMN not in df.columns:
|
||||
errors.append(
|
||||
f"Missing required column '{DATE_COLUMN}'. "
|
||||
f"Update DATE_COLUMN in config.py or add fallback columns."
|
||||
)
|
||||
|
||||
if len(df) == 0:
|
||||
errors.append(
|
||||
f"DataFrame is empty. Check date filters (MIN_YEAR, MAX_DATE) in config.py."
|
||||
)
|
||||
|
||||
if errors:
|
||||
error_msg = "Data validation failed:\n" + "\n".join(f" - {e}" for e in errors)
|
||||
error_msg += "\n\nRun: python config_validator.py for detailed validation"
|
||||
return False, error_msg
|
||||
|
||||
return True, "OK"
|
||||
```
|
||||
|
||||
## Warning Messages
|
||||
|
||||
### When to Use Warnings
|
||||
|
||||
Use warnings (not errors) for:
|
||||
- Non-critical data quality issues
|
||||
- Optional features that aren't configured
|
||||
- Deprecated functionality
|
||||
- Performance considerations
|
||||
|
||||
### Warning Format
|
||||
|
||||
```python
|
||||
import warnings
|
||||
|
||||
# Good: Informative warning
|
||||
if date_coverage < 0.9: # Less than 90% but not critical
|
||||
warnings.warn(
|
||||
f"Date coverage is {date_coverage:.1%} ({missing_count:,} rows missing dates).\n"
|
||||
f"Consider adding fallback date columns to improve coverage.\n"
|
||||
f"See .cursor/rules/data_loading.md for details.",
|
||||
UserWarning
|
||||
)
|
||||
```
|
||||
|
||||
## Logging Errors
|
||||
|
||||
### Use Structured Logging
|
||||
|
||||
```python
|
||||
from logger_config import get_logger
|
||||
|
||||
logger = get_logger('analysis_name')
|
||||
|
||||
try:
|
||||
df = load_sales_data(get_data_path())
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"Failed to load data: {e}",
|
||||
exc_info=True, # Include stack trace
|
||||
extra={
|
||||
'file_path': str(get_data_path()),
|
||||
'config_file': 'config.py',
|
||||
'suggestion': 'Run config_validator.py to check configuration'
|
||||
}
|
||||
)
|
||||
raise
|
||||
```
|
||||
|
||||
## AI-Friendly Error Messages
|
||||
|
||||
### Help AI Understand and Fix
|
||||
|
||||
Error messages should help AI assistants:
|
||||
1. Understand what went wrong
|
||||
2. Know where to look for fixes
|
||||
3. Suggest specific solutions
|
||||
4. Reference relevant documentation
|
||||
|
||||
```python
|
||||
# Good: AI can parse and act on this
|
||||
if column not in df.columns:
|
||||
raise ValueError(
|
||||
f"Column '{column}' not found.\n"
|
||||
f"Available: {list(df.columns)}\n"
|
||||
f"Fix: Update {column}_COLUMN in config.py\n"
|
||||
f"See: .cursor/rules/data_loading.md"
|
||||
)
|
||||
|
||||
# Bad: AI has no context
|
||||
if column not in df.columns:
|
||||
raise ValueError("Not found")
|
||||
```
|
||||
|
||||
## Error Recovery
|
||||
|
||||
### Provide Recovery Options
|
||||
|
||||
```python
|
||||
# Good: Offers recovery path
|
||||
def load_sales_data(filepath=None):
|
||||
try:
|
||||
df = pd.read_csv(filepath)
|
||||
except FileNotFoundError:
|
||||
# Suggest alternatives
|
||||
suggestions = [
|
||||
f"1. Check file path: {filepath}",
|
||||
f"2. Update DATA_FILE in config.py",
|
||||
f"3. Run: python setup_wizard.py",
|
||||
f"4. Generate sample data: python generate_sample_data.py"
|
||||
]
|
||||
raise FileNotFoundError(
|
||||
f"Data file not found: {filepath}\n"
|
||||
f"\n"
|
||||
f"Options:\n" + "\n".join(suggestions)
|
||||
)
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
Good error handling:
|
||||
- ✅ Specific and actionable
|
||||
- ✅ Provides context
|
||||
- ✅ Suggests solutions
|
||||
- ✅ References documentation
|
||||
- ✅ Helps both users and AI assistants
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** January 2026
|
||||
**For:** Error handling in sales_analysis_template
|
||||
Reference in New Issue
Block a user