diff --git a/edge/zones.py b/edge/zones.py index 91af6f2..23718ff 100644 --- a/edge/zones.py +++ b/edge/zones.py @@ -5,7 +5,10 @@ from edge.detectors.zone import Zone def zones_from_config(config: dict) -> list[Zone]: out: list[Zone] = [] - for row in config.get("zones", []) or []: + rows = config.get("zones", []) or [] + if not isinstance(rows, list): + return [] + for row in rows: try: raw = row["polygon_json"] pts = json.loads(raw) if isinstance(raw, str) else raw @@ -13,7 +16,7 @@ def zones_from_config(config: dict) -> list[Zone]: if len(polygon) < 3: continue out.append(Zone(str(row["zone_id"]), str(row["level"]), polygon)) - except (KeyError, ValueError, TypeError, json.JSONDecodeError): + except (KeyError, ValueError, TypeError, IndexError, json.JSONDecodeError): continue return out diff --git a/tests/test_zones.py b/tests/test_zones.py index 67f015b..1fcb342 100644 --- a/tests/test_zones.py +++ b/tests/test_zones.py @@ -19,3 +19,15 @@ def test_skips_malformed_row(): def test_empty_config(): assert zones_from_config({}) == [] assert thresholds_from_config({}) == {} + +def test_skips_short_point_without_crashing(): + cfg = {"zones": [ + {"zone_id": "bad", "camera_id": "c", "level": "restricted", "polygon_json": "[[0,0],[9],[9,9]]"}, + {"zone_id": "ok", "camera_id": "c", "level": "restricted", "polygon_json": "[[0,0],[9,0],[9,9]]"}, + ]} + zones = zones_from_config(cfg) + # bad row skipped, good row survives -- function did not crash + assert [z.zone_id for z in zones] == ["ok"] + +def test_non_iterable_zones_returns_empty(): + assert zones_from_config({"zones": 5}) == []