From 2881f777c214e9171f767bfad7299e125190c996 Mon Sep 17 00:00:00 2001 From: IFAKA Date: Fri, 19 Dec 2025 09:36:14 +0100 Subject: [PATCH] Handle malformed API response values in model parsing Add safe type conversion helpers to prevent ValueError crashes when API returns non-numeric values for numeric fields. --- src/discourses/models.py | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/discourses/models.py b/src/discourses/models.py index 35d0fac..8eb61d1 100644 --- a/src/discourses/models.py +++ b/src/discourses/models.py @@ -9,6 +9,26 @@ from typing import Any, Dict, List, Optional +def _safe_float(value: Any, default: float = 0.0) -> float: + """Safely convert value to float, returning default on failure.""" + if value is None: + return default + try: + return float(value) + except (ValueError, TypeError): + return default + + +def _safe_int(value: Any, default: int = 0) -> int: + """Safely convert value to int, returning default on failure.""" + if value is None: + return default + try: + return int(value) + except (ValueError, TypeError): + return default + + @dataclass class AnalysisResult: """ @@ -51,17 +71,17 @@ def from_dict(cls, data: Dict[str, Any]) -> "AnalysisResult": return cls( label=classification.get("label", "neutral"), - confidence=float(classification.get("confidence", 0)), - outlook=float(scores.get("outlook", 0)), + confidence=_safe_float(classification.get("confidence")), + outlook=_safe_float(scores.get("outlook")), scores={ - "bullish": float(scores.get("bullish", 0)), - "bearish": float(scores.get("bearish", 0)), - "neutral": float(scores.get("neutral", 0)), - "confusion": float(scores.get("confusion", 0)), + "bullish": _safe_float(scores.get("bullish")), + "bearish": _safe_float(scores.get("bearish")), + "neutral": _safe_float(scores.get("neutral")), + "confusion": _safe_float(scores.get("confusion")), }, - word_count=int(analysis.get("word_count", 0)), - matched_count=int(analysis.get("matched_count", 0)), - negation_count=int(analysis.get("negation_count", 0)), + word_count=_safe_int(analysis.get("word_count")), + matched_count=_safe_int(analysis.get("matched_count")), + negation_count=_safe_int(analysis.get("negation_count")), raw=data, )