From 9decd0ba5d31dff3c34050d93a85083750ddf9df Mon Sep 17 00:00:00 2001 From: LemonNexus Date: Mon, 9 Feb 2026 14:35:12 +0000 Subject: [PATCH] fix(api): handle null/None values in API parsing Added safe_decimal() helper to handle None/empty values from API that were causing decimal.ConversionSyntax errors. Fixed parsers: - NexusHealingTool: Uses safe_decimal for decay/heal amounts - NexusRing: Uses safe_decimal for max_tt/min_tt - NexusClothing: Safely handles None buff values Errors were occurring when API returned null for numeric fields instead of 0. --- core/nexus_full_api.py | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/core/nexus_full_api.py b/core/nexus_full_api.py index 4b186e4..3654dc4 100644 --- a/core/nexus_full_api.py +++ b/core/nexus_full_api.py @@ -3,7 +3,7 @@ Complete Entropia Nexus API Integration for Lemontropia Suite Fetches all gear types: weapons, armors, plates, attachments, enhancers, healing, rings, clothes, pets """ -from decimal import Decimal +from decimal import Decimal, InvalidOperation from dataclasses import dataclass from typing import Optional, List, Dict, Any import requests @@ -191,6 +191,16 @@ class NexusEnhancer(NexusItem): ) +def safe_decimal(value: Any, default: str = "0") -> Decimal: + """Safely convert a value to Decimal, handling None and invalid values.""" + if value is None or value == "": + return Decimal(default) + try: + return Decimal(str(value)) + except (InvalidOperation, ValueError, TypeError): + return Decimal(default) + + @dataclass class NexusHealingTool(NexusItem): """Healing tool from Entropia Nexus API.""" @@ -208,8 +218,8 @@ class NexusHealingTool(NexusItem): economy = props.get('Economy', {}) heal = props.get('Heal', {}) - decay = Decimal(str(economy.get('Decay', 0))) - heal_amount = Decimal(str(heal.get('Amount', 0))) + decay = safe_decimal(economy.get('Decay')) + heal_amount = safe_decimal(heal.get('Amount')) heal_per_pec = heal_amount / decay if decay > 0 else Decimal('0') return cls( @@ -221,7 +231,7 @@ class NexusHealingTool(NexusItem): decay=decay, heal_per_pec=heal_per_pec, type=props.get('Type', 'fap'), - profession_level=int(props.get('RequiredLevel', 0)), + profession_level=int(props.get('RequiredLevel', 0) or 0), is_limited='(L)' in data.get('Name', ''), ) @@ -242,14 +252,14 @@ class NexusRing(NexusItem): props = data.get('Properties', {}) economy = props.get('Economy', {}) effects_data = props.get('Effects', {}) - + # Parse effects (usually under "Effects on Equip") effects = {} if 'Effects on Equip' in effects_data: effects = effects_data['Effects on Equip'] elif isinstance(effects_data, dict): effects = effects_data - + return cls( id=data.get('Id', 0), name=data.get('Name', 'Unknown'), @@ -258,8 +268,8 @@ class NexusRing(NexusItem): slot=props.get('Slot', 'Left Finger'), gender=props.get('Gender', 'Both'), effects=effects, - max_tt=Decimal(str(economy.get('MaxTT', 0))), - min_tt=Decimal(str(economy.get('MinTT', 0))), + max_tt=safe_decimal(economy.get('MaxTT')), + min_tt=safe_decimal(economy.get('MinTT')), is_limited='(L)' in data.get('Name', ''), ) @@ -270,13 +280,19 @@ class NexusClothing(NexusItem): slot: str # 'face', 'body', 'legs', 'feet' buffs: Dict[str, Decimal] is_cosmetic: bool - + @classmethod def from_api(cls, data: Dict[str, Any]) -> "NexusClothing": """Create from API response.""" props = data.get('Properties', {}) - buffs = {k: Decimal(str(v)) for k, v in props.get('Buffs', {}).items()} - + buffs_raw = props.get('Buffs', {}) or {} + buffs = {} + for k, v in buffs_raw.items(): + try: + buffs[k] = safe_decimal(v) + except: + buffs[k] = Decimal('0') + return cls( id=data.get('Id', 0), name=data.get('Name', 'Unknown'),