Skip to content

Error Handling

This tutorial describes the exceptions pysenxor can raise and how to handle them. Use try/except to recover from transient failures (e.g. device unplugged) or to fail cleanly when the device or hardware is not usable.

1. Error types in pysenxor

All errors live in senxor.error. They are normal runtime conditions, not programming bugs.

Exception When it happens
SenxorNotConnectedError You call methods like read() or start_stream() when the device is not connected or already closed.
SenxorLostConnectionError The device was connected but the link dropped (e.g. USB unplugged, cable fault) while you were using it.
SenxorUnexpectedAckError The device sent an ACK that was not expected for the current operation.
SenxorAckInvalidError The device sent an ACK with invalid format or content.
SenxorResponseTimeoutError No response from the device within the expected time.
SenxorNoModuleError The board has no thermal imaging lens module attached.

About SenxorNoModuleError: The dev board is made of an MCU chip and a thermal imaging lens. If the lens module is not installed, read() will raise SenxorNoModuleError because there is no image data. You can still perform some register and field operations; only lens-dependent data is unavailable. Fields that depend on the lens (e.g. SERIAL_NUMBER) will return 0 when no module is present.

2. Catching and handling errors

Use try/except around connect, stream start, and read. Handle the exceptions you care about and exit or retry as appropriate.

from senxor import connect, list_senxor
from senxor.error import (
    SenxorLostConnectionError,
    SenxorNoModuleError,
    SenxorNotConnectedError,
)

devices = list_senxor("serial")
if not devices:
    raise ValueError("No devices found")

try:
    dev = connect(devices[0])
    dev.start_stream()
    while True:
        header, frame = dev.read()
        if frame is not None:
            print(f"Frame shape: {frame.shape}")
except SenxorNoModuleError:
    print("No lens module installed; cannot read frames.")
    dev.close()
except (SenxorNotConnectedError, SenxorLostConnectionError) as e:
    print(f"Connection problem: {e}")
    if dev:
        dev.close()

3. Auto-reconnect on lost connection

When you read frames in a loop, the device may disconnect (e.g. cable unplugged). You can catch SenxorLostConnectionError, try to reconnect a limited number of times, and exit if reconnection fails.

Flow:

  1. Connect and start the stream.
  2. In a loop, call read(). On success, process the frame and continue.
  3. On SenxorLostConnectionError, close the old connection and try to reconnect (e.g. re-enumerate and connect() again), then start_stream(). Retry up to 3 times.
  4. If all retries fail, log or print and exit the loop.

Example: reconnect up to 3 times then exit

from senxor import connect, list_senxor
from senxor.error import SenxorLostConnectionError

MAX_RECONNECT = 3

devices = list_senxor("serial")
if not devices:
    raise ValueError("No devices found")

dev = connect(devices[0])
dev.start_stream()

while True:
    try:
        header, frame = dev.read()
        if frame is not None:
            print(f"Frame shape: {frame.shape}")
    except SenxorLostConnectionError:
        dev.close()
        for attempt in range(MAX_RECONNECT):
            devices = list_senxor("serial")
            if not devices:
                print(f"Reconnect attempt {attempt + 1}/{MAX_RECONNECT}: no devices")
                continue
            try:
                dev = connect(devices[0])
                dev.start_stream()
                print("Reconnected.")
                break
            except Exception as e:
                print(f"Reconnect attempt {attempt + 1}/{MAX_RECONNECT} failed: {e}")
        else:
            print("Reconnect failed after", MAX_RECONNECT, "attempts. Exiting.")
            break

After 3 failed reconnect attempts the loop exits. You can replace the print calls with your own logging or error reporting.