Exceptions
Both backends map their errors onto the same neutral hierarchy, so
except ModbusError catches everything regardless of which backend produced it.
Every ModbusUnit method raises on failure — it never returns None.
ModbusError├── ModbusConnectionError├── ModbusTimeoutError (also a builtin TimeoutError)├── ModbusExceptionError (.exception_code)└── ModbusProtocolErrorImport them from the top-level package:
from modbus_connection import ( ModbusError, ModbusConnectionError, ModbusTimeoutError, ModbusExceptionError, ModbusProtocolError,)The hierarchy
Section titled “The hierarchy”ModbusError
Section titled “ModbusError”The base class. Catch it to handle any Modbus failure uniformly:
try: values = await unit.read_holding_registers(0, 10)except ModbusError as err: log.warning("read failed: %s", err)ModbusConnectionError
Section titled “ModbusConnectionError”The link is down, not connected, or the transport failed. Recreating the connection is the owner’s job — the abstraction never self-reconnects.
ModbusTimeoutError
Section titled “ModbusTimeoutError”An operation timed out: a request got no valid response in time, or a connect
attempt did not complete in time. It also subclasses the builtin TimeoutError,
so except TimeoutError catches it too:
try: await unit.read_holding_registers(0, 1)except TimeoutError: # catches ModbusTimeoutError ...ModbusExceptionError
Section titled “ModbusExceptionError”The device returned a Modbus exception response — it understood the request
but refused it (illegal address, illegal value, and so on). The raw code is on
.exception_code:
try: await unit.write_register(40, 99)except ModbusExceptionError as err: if err.exception_code == 3: # illegal data value ...ModbusProtocolError
Section titled “ModbusProtocolError”A reply arrived but was not a valid frame — bad CRC/LRC, framing, or a
mismatched header. Only backends that can tell a garbled reply from a missing one
raise it: tmodbus does; pymodbus cannot, and surfaces both a garbled and a
missing reply as ModbusTimeoutError.
Backend differences
Section titled “Backend differences”| Situation | pymodbus | tmodbus |
|---|---|---|
| No response in time | ModbusTimeoutError |
ModbusTimeoutError |
| Garbled / corrupt reply | ModbusTimeoutError |
ModbusProtocolError |
| Device exception response | ModbusExceptionError |
ModbusExceptionError |
| Link down | ModbusConnectionError |
ModbusConnectionError |
If you need to distinguish a corrupt reply from a silent timeout, use tmodbus. If
you catch ModbusError (or ModbusTimeoutError plus ModbusExceptionError) your
code is correct on both.
Not-implemented function codes
Section titled “Not-implemented function codes”A backend that can’t implement a given Modbus function code raises the builtin
NotImplementedError (not part of the ModbusError tree). tmodbus does this for
diagnostics and the comm-event codes, and for the UDP / ASCII-over-TCP transports.