Exceptions¶
Structured exception hierarchy for distinguishing error categories.
Design Intent¶
All kazunoko exceptions inherit from KazunokoError, so callers can catch everything with one clause or handle specific categories selectively. Timeout errors are subclasses of their parent error type (not a separate branch) so a catch on ResponseError also catches ResponseTimeout.
Hierarchy¶
KazunokoError
├── DeviceError — connection and port initialization failures
├── CommandError — failures sending a command to the device
│ └── CommandTimeout — command send timed out
├── ResponseError — invalid or missing response from device
│ └── ResponseTimeout — no response received within timeout
└── ProtocolError — JSON parse failure or unexpected protocol data
Exception reference¶
| Exception | When raised | Typical cause |
|---|---|---|
DeviceError |
connect(), PortDevice.__init__ |
Port not found, port in use, driver missing |
CommandError |
send_command() |
Device disconnected mid-session |
CommandTimeout |
send_command() |
Device unresponsive |
ResponseError |
receive_response() |
Malformed JSON, missing type field |
ResponseTimeout |
receive_response() |
No data within timeout seconds |
ProtocolError |
parse_jsonl() |
JSON parse failure, type mismatch |
Usage patterns¶
Catch all kazunoko errors:
from kazunoko.exceptions import KazunokoError
try:
with connect() as device:
response = device.query("GET_STATUS")
except KazunokoError as e:
print(f"Error: {e}")
Handle specific categories:
from kazunoko.exceptions import DeviceError, ResponseTimeout, ResponseError
try:
with connect() as device:
response = device.query("GET_STATUS")
except DeviceError as e:
print(f"Could not connect: {e}")
except ResponseTimeout:
print("Device did not respond — try kazunoko reset")
except ResponseError as e:
print(f"Invalid response: {e}")
Exception chaining — kazunoko exceptions always chain the underlying cause (raise KazunokoError(...) from e), so the original serial.SerialException or json.JSONDecodeError is accessible via e.__cause__ for debugging.
Streaming and skipped events¶
In streaming contexts (Reader, Measure), ResponseTimeout and ProtocolError are caught internally — the event is skipped and counted in StreamingStats rather than aborting the whole collection. DeviceError and CommandError are not caught and propagate immediately, since they indicate the connection itself has failed.