Skip to content

Replace print() error messages with proper exceptions #29

@jlixfeld

Description

@jlixfeld

Problem

The codebase contains validation methods that use print() statements for error reporting instead of raising proper exceptions. This creates several issues:

Current pattern in aggregation.py:252-278:

def validate_input(self, data: PolarsDataFrame | PandasDataFrame) -> bool:
    """Validate input data format."""
    if missing_cols:
        print(f"ERROR: Missing required columns: {missing_cols}")
        return False
    
    if not TimeframeConfig.validate_timeframe(tf):
        print(f"ERROR: Invalid timeframe '{tf}'")
        return False
    
    if len(df) < 2:
        print(f"ERROR: Insufficient data points ({len(df)} < 2)")
        return False
    
    return True

Problems:

  1. Silent failures: Calling code gets False but must check stdout for details
  2. Not testable: Cannot catch/assert on specific error types in tests
  3. Not production-ready: Library code should never print to stdout
  4. Poor separation of concerns: Validation logic mixed with I/O
  5. Not composable: Cannot differentiate between error types programmatically

Proposed Solution

Replace print() + return False pattern with proper exception raising:

def validate_input(self, data: PolarsDataFrame | PandasDataFrame) -> None:
    """Validate input data format.
    
    Raises:
        ValueError: If required columns are missing
        ValueError: If timeframe values are invalid
        ValueError: If insufficient data points
    """
    df = self._convert_to_polars(data)
    
    required_cols = IndicatorSchema.get_required_input_columns()
    missing_cols = [col for col in required_cols if col not in df.columns]
    
    if missing_cols:
        raise ValueError(f"Missing required columns: {missing_cols}")
    
    unique_timeframes = df["timeframe"].unique().to_list()
    for tf in unique_timeframes:
        if not TimeframeConfig.validate_timeframe(tf):
            raise ValueError(f"Invalid timeframe: {tf}")
    
    if len(df) < 2:
        raise ValueError(f"Insufficient data points: {len(df)} (minimum: 2)")

Files to Update

Search for all print( statements in production code (excluding tests):

  • thestrat/aggregation.py:263,270,275
  • Any other print() statements in thestrat/*.py

Docstring examples with print() are fine - only fix actual error handling.

Benefits

  1. Proper error handling: Calling code can catch specific exceptions
  2. Better testing: Can assert on exception types and messages
  3. Production-ready: No stdout pollution in library code
  4. Type safety: Return type changes from bool to None (validates or raises)
  5. Clearer API: Exceptions document failure modes in docstrings

Implementation Notes

  • Change return type from bool to None
  • Update all callers to handle exceptions instead of checking boolean
  • Add Raises: section to docstrings documenting exception types
  • Consider using custom exception classes if needed (e.g., ValidationError)
  • Ensure all tests are updated to expect exceptions

Breaking Change

This is a breaking change - callers checking if validate_input(data): will need to update to:

try:
    validate_input(data)
except ValueError as e:
    # Handle validation error
    pass

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestzero-technical-debtZero technical debt implementation with complete removal of legacy code

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions