From 57c6ca4a00397db4e5aa3ea013b4c4a6b4b03d70 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Tue, 17 Feb 2026 17:42:21 -0700 Subject: [PATCH] Make get_device_status resilient to individual USB command failures Wrap get_usb_speed, get_serial_number, and get_last_error in try/except so a STALL on one command returns "unavailable" instead of crashing the entire status read. Discovered when vendor command 0x07 (get_usb_speed) STALLs on real hardware despite working firmware version readback. --- mcp/skywalker-mcp/src/skywalker_mcp/server.py | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/mcp/skywalker-mcp/src/skywalker_mcp/server.py b/mcp/skywalker-mcp/src/skywalker_mcp/server.py index 53e4a33..d590474 100644 --- a/mcp/skywalker-mcp/src/skywalker_mcp/server.py +++ b/mcp/skywalker-mcp/src/skywalker_mcp/server.py @@ -161,16 +161,30 @@ async def get_device_status(ctx: Context) -> dict: with bridge.lock: fw = bridge._dev.get_fw_version() config = bridge._dev.get_config() - speed = bridge._dev.get_usb_speed() - serial = bridge._dev.get_serial_number() - error = bridge._dev.get_last_error() + # Some commands may STALL on certain firmware builds; don't let + # one failure kill the entire status read. + try: + speed_raw = bridge._dev.get_usb_speed() + speed = {0: "unknown", 1: "Full (12 Mbps)", 2: "High (480 Mbps)"}.get( + speed_raw, f"unknown ({speed_raw})") + except Exception: + speed = "unavailable" + try: + serial = bridge._dev.get_serial_number().hex(' ') + except Exception: + serial = "unavailable" + try: + error_code = bridge._dev.get_last_error() + error = ERROR_NAMES.get(error_code, f"0x{error_code:02X}") + except Exception: + error = "unavailable" return { "firmware": fw, "config_byte": config, "config_bits": {name: is_set for name, is_set in format_config_bits(config)}, - "usb_speed": {0: "unknown", 1: "Full (12 Mbps)", 2: "High (480 Mbps)"}.get(speed, f"unknown ({speed})"), - "serial": serial.hex(' '), - "last_error": ERROR_NAMES.get(error, f"0x{error:02X}"), + "usb_speed": speed, + "serial": serial, + "last_error": error, } return await asyncio.to_thread(_read)