Skip to content

watlowlib.errors

The typed exception hierarchy and ErrorContext dataclass. Every public-facing error inherits from WatlowError; protocol-specific errors carry per-protocol context (Std Bus class/member/instance, Modbus register address / function code) on error.context. See Troubleshooting for the common-error table.

Public surface

watlowlib.errors

Typed exception hierarchy for :mod:watlowlib.

Every library exception inherits from :class:WatlowError and carries a structured :class:ErrorContext. See docs/design.md §8.

ErrorContext selector fields are populated per-protocol:

  • Std Bus failures fill cls / member / instance.
  • Modbus failures fill register_address / function_code.

Wire-level fields (request / response / elapsed_s) are best- effort and may be None for failures raised before I/O.

:class:WatlowCapabilityWarning, :class:WatlowCapabilityError, and :class:WatlowFirmwareError are reserved as part of the planned capability-gate hierarchy (design §5). They are exported for callers that want to except on them without pinning a future minor; the library does not currently emit any of the three. Capability mismatches on writes (e.g. cool-side gains on a heat-only PM) currently surface as :class:WatlowConfigurationError.

ErrorContext dataclass

ErrorContext(
    command_name=None,
    protocol=None,
    port=None,
    address=None,
    parameter_id=None,
    cls=None,
    member=None,
    instance=None,
    register_address=None,
    function_code=None,
    request=None,
    response=None,
    elapsed_s=None,
)

Structured context attached to every :class:WatlowError.

Fields are best-effort — missing data is None rather than raising.

WatlowCapabilityError

WatlowCapabilityError(message='', *, context=None)

Bases: WatlowError

Command is not available on this device / firmware / family.

Reserved for the planned capability-gate hierarchy. The library does not currently raise this — capability mismatches surface as :class:WatlowConfigurationError today (see commands/loop.py).

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowCapabilityWarning

Bases: UserWarning

Reserved warning class — not currently emitted.

Planned use is non-strict family-prior mismatches (attempt the command, warn, update availability from the device's response). The library does not currently emit this; the warning class is exported so callers can pre-register filters.

WatlowConfigurationError

WatlowConfigurationError(message='', *, context=None)

Bases: WatlowError

Configuration-level error (bad args, conflicting settings).

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowConfirmationRequiredError

WatlowConfirmationRequiredError(
    message="", *, context=None
)

Bases: WatlowConfigurationError

A PERSISTENT / DANGEROUS command was attempted without confirm=True.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowConnectionError

WatlowConnectionError(message='', *, context=None)

Bases: WatlowTransportError

Could not open / lost the connection to the device.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowError

WatlowError(message='', *, context=None)

Bases: Exception

Base class for every :mod:watlowlib exception.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowFirmwareError

WatlowFirmwareError(message='', *, context=None)

Bases: WatlowCapabilityError

Command is outside the supported firmware window.

Reserved alongside :class:WatlowCapabilityError; not currently emitted by the library.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowFrameError

WatlowFrameError(message='', *, context=None)

Bases: WatlowProtocolError

Bad CRC, bad length, malformed framing, etc.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowModbusError

WatlowModbusError(message='', *, context=None)

Bases: WatlowProtocolError

Base class for Modbus-layer errors.

Wraps every anymodbus exception so callers see one error hierarchy regardless of protocol. __cause__ preserves the original anymodbus exception for callers that need it.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowModbusIllegalDataAddressError

WatlowModbusIllegalDataAddressError(
    message="", *, context=None
)

Bases: WatlowModbusError, WatlowProtocolUnsupportedError

Modbus exception 0x02 — register address not allowed.

Maps to :class:Availability.UNSUPPORTED in the session cache.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowModbusIllegalDataValueError

WatlowModbusIllegalDataValueError(
    message="", *, context=None
)

Bases: WatlowModbusError

Modbus exception 0x03 — bad argument, not absence.

Does not affect availability (the parameter exists; the write value was simply rejected).

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowModbusIllegalFunctionError

WatlowModbusIllegalFunctionError(
    message="", *, context=None
)

Bases: WatlowModbusError, WatlowProtocolUnsupportedError

Modbus exception 0x01 — slave does not implement the function.

Maps to :class:Availability.UNSUPPORTED in the session cache. Inherits :class:WatlowProtocolUnsupportedError so the session's sticky-unsupported handling treats it like Std Bus 0x81 / 0x83.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowModbusSlaveFailureError

WatlowModbusSlaveFailureError(message='', *, context=None)

Bases: WatlowModbusError

Modbus exception 0x04 — unrecoverable slave-side error.

Does not affect availability — non-response is not a refusal of the parameter (per design §5b table).

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowModbusTimeoutError

WatlowModbusTimeoutError(message='', *, context=None)

Bases: WatlowModbusError, WatlowTimeoutError

Modbus request timed out at the protocol layer.

Inherits :class:WatlowTimeoutError so callers with existing timeout-handling code see this as a transport timeout. Does not affect availability.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowNoSuchAttributeError

WatlowNoSuchAttributeError(message='', *, context=None)

Bases: WatlowProtocolError

Standard Bus error 0x83 — valid class, invalid member.

Maps to :class:Availability.UNSUPPORTED in the session cache.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowNoSuchInstanceError

WatlowNoSuchInstanceError(message='', *, context=None)

Bases: WatlowProtocolError

Standard Bus error 0x84 — valid class+member, invalid instance.

The parameter exists but the requested loop / channel does not. Does not affect availability (a different instance may succeed).

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowNoSuchObjectError

WatlowNoSuchObjectError(message='', *, context=None)

Bases: WatlowProtocolError

Standard Bus error 0x81 — invalid class.

The device does not expose the requested object class. Maps to :class:Availability.UNSUPPORTED in the session cache.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowProtocolError

WatlowProtocolError(message='', *, context=None)

Bases: WatlowError

Protocol-level error (framing, parsing, unrecognised reply).

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowProtocolUnsupportedError

WatlowProtocolUnsupportedError(message='', *, context=None)

Bases: WatlowProtocolError

The active protocol cannot satisfy this command on this device.

Sticky for the session: subsequent attempts at the same command short-circuit with this error pre-I/O. Set on Std Bus 0x81 / 0x83 and on Modbus IllegalFunction / IllegalDataAddress per docs/design.md §5b.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowSinkDependencyError

WatlowSinkDependencyError(message='', *, context=None)

Bases: WatlowSinkError

An optional sink extra is not installed.

Raised by sinks behind a [parquet] / [postgres] extra when the backing dependency (pyarrow, asyncpg) is missing at :meth:open time. Instantiating the sink succeeds on bare-core installs; the dependency check is deferred so import-time errors don't break callers that never reach for the extra.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowSinkError

WatlowSinkError(message='', *, context=None)

Bases: WatlowError

Base class for :mod:watlowlib.sinks errors.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowSinkSchemaError

WatlowSinkSchemaError(message='', *, context=None)

Bases: WatlowSinkError

The target sink's existing schema does not match what the row carries.

Raised when a sink configured with create_table=False is pointed at a missing or incompatible backing schema.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowSinkWriteError

WatlowSinkWriteError(message='', *, context=None)

Bases: WatlowSinkError

A sink-backend write failed (CREATE TABLE, INSERT, file IO, ...).

__cause__ preserves the backend-native exception (sqlite3.Error, OSError, ...) for callers that want to inspect it.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowTimeoutError

WatlowTimeoutError(message='', *, context=None)

Bases: WatlowTransportError

A transport read or write timed out.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowTransportError

WatlowTransportError(message='', *, context=None)

Bases: WatlowError

I/O-layer error from the transport.

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()

WatlowValidationError

WatlowValidationError(message='', *, context=None)

Bases: WatlowConfigurationError

Request validation failed before I/O (bad instance, bad value).

Source code in src/watlowlib/errors.py
def __init__(self, message: str = "", *, context: ErrorContext | None = None) -> None:
    super().__init__(message)
    self.context = context or ErrorContext()