fix: degrade gracefully when pyserial is missing
A stale venv after a code update (editable install + git pull) left pyserial out of the environment, and the hard module-level import in wireview.py took the entire web server down — even on machines without a WireView device. Guard the import: without pyserial the serial transport is disabled (one-time warning, connect fails, reads return None) while the rest of the server keeps running. The hwmon transport is unaffected. Also simplify the except clauses to OSError (SerialException is an OSError subclass) so they no longer reference the possibly-None module.
This commit is contained in:
1 parent
526b71b45f
commit
b8e91e3c91
2 files changed
+68
-10
No files matched your search
@@ -469,6 +469,40 @@ def test_serial_device_no_response():
|
||||
t.join(timeout=2)
|
||||
|
||||
|
||||
def test_serial_transport_missing_pyserial():
|
||||
"""A missing pyserial degrades gracefully: connect fails, reads are
|
||||
None, and the warning is logged once — not on every attempt."""
|
||||
import logging
|
||||
|
||||
records: list[str] = []
|
||||
|
||||
class Capture(logging.Handler):
|
||||
def emit(self, record: logging.LogRecord) -> None:
|
||||
records.append(record.getMessage())
|
||||
|
||||
logger = logging.getLogger("nvcurve.wireview")
|
||||
handler = Capture()
|
||||
old_level = logger.level
|
||||
logger.addHandler(handler)
|
||||
logger.setLevel(logging.WARNING)
|
||||
try:
|
||||
with mock.patch.object(wv, "serial", None):
|
||||
wv._serial_missing_warned = False
|
||||
dev = wv.WireViewSerialDevice("/dev/ttyACM99")
|
||||
check("no-pyserial connect", not dev.connect())
|
||||
check("no-pyserial not rejected", not dev.rejected)
|
||||
check("no-pyserial sample", dev.read_sample() is None)
|
||||
# A second attempt must not re-warn.
|
||||
dev2 = wv.WireViewSerialDevice("/dev/ttyACM99")
|
||||
check("no-pyserial second attempt", not dev2.connect())
|
||||
warnings = [r for r in records if "pyserial" in r]
|
||||
check("no-pyserial warns once", len(warnings) == 1)
|
||||
finally:
|
||||
logger.removeHandler(handler)
|
||||
logger.setLevel(old_level)
|
||||
wv._serial_missing_warned = False
|
||||
|
||||
|
||||
def main() -> int:
|
||||
print("wireview tests:")
|
||||
test_parse_sensor_struct()
|
||||
@@ -485,6 +519,7 @@ def main() -> int:
|
||||
test_serial_device_protocol()
|
||||
test_serial_device_rejected_product()
|
||||
test_serial_device_no_response()
|
||||
test_serial_transport_missing_pyserial()
|
||||
print(f"\n{PASS} passed, {FAIL} failed")
|
||||
return 1 if FAIL else 0
|
||||
|
||||
|
||||
Reference in new issue
Block a user