summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorAdam Smith <adamsmith@yzguy.io>2026-09-29 19:30:18 +0000
committerChristian Breunig <christian@breunig.cc>2026-09-30 06:13:50 +0200
commit1aa2cd1df614925cf68964239eeaaf42ea74bc43 (patch)
tree58bd2c3d88f73ddf04244664bc7d150ee29aa314 /python
parent002050d158356078931d1a196538b5803eab788e (diff)
downloadvyos-1x-1aa2cd1df614925cf68964239eeaaf42ea74bc43.tar.gz
vyos-1x-1aa2cd1df614925cf68964239eeaaf42ea74bc43.zip
wwan: T7487: catch malformed mmcli JSON, not just OSError
mmcli can return empty or non-JSON output while ModemManager is still starting (T6604), and json.loads() raising on that is a ValueError, not an OSError - it was propagating straight out of _modem_owning_port() uncaught. Under wait=True that reaches wait_for()'s callback and aborts the poll loop instead of retrying, exactly the startup race this module exists to ride out. Co-authored-by: Christian Breunig <christian@breunig.cc>
Diffstat (limited to 'python')
-rw-r--r--python/vyos/utils/wwan.py18
1 files changed, 13 insertions, 5 deletions
diff --git a/python/vyos/utils/wwan.py b/python/vyos/utils/wwan.py
index af719571d..8ee6a5a9a 100644
--- a/python/vyos/utils/wwan.py
+++ b/python/vyos/utils/wwan.py
@@ -59,17 +59,25 @@ def _modem_owning_port(ifname: str):
from json import loads
try:
- modem_list = loads(cmdl(['mmcli', '--list-modems', '--output-json'])).get(
- 'modem-list', []
- )
- except OSError:
+ data = loads(cmdl(['mmcli', '--list-modems', '--output-json']))
+ except (OSError, ValueError):
+ # ValueError also catches json.JSONDecodeError - mmcli can return
+ # empty or malformed output while ModemManager is still starting
+ # (T6604), and that must retry under wait=True, not abort it.
+ return None
+
+ # Well-formed JSON of an unexpected shape is treated like no modems at all
+ modem_list = []
+ if isinstance(data, dict) and 'modem-list' in data:
+ modem_list = data['modem-list']
+ if not isinstance(modem_list, list):
return None
for modem_path in modem_list:
idx = modem_path.rsplit('/', 1)[-1]
try:
detail = loads(cmdl(['mmcli', '--modem', idx, '--output-json']))
- except OSError:
+ except (OSError, ValueError):
continue
ports = dict_search('modem.generic.ports', detail) or []
if any(port.split(' ')[0] == ifname for port in ports):