fujilib.errors¶
The typed exception hierarchy and ErrorContext (design §9).
fujilib.errors ¶
Typed exception hierarchy for :mod:fujilib (design §9).
Every library exception inherits from :class:FujiError and carries a
structured :class:ErrorContext. The message is the human-readable
summary; the context is the machine-readable detail (command, protocol, port,
station address, channel, register and function code, request/response bytes,
elapsed time).
The pattern matches the *lib family: ErrorContext is a frozen
dataclass(slots=True) whose extra mapping is always frozen into a
read-only :class:types.MappingProxyType, and :meth:FujiError.with_context
does a slot-safe copy so an inner layer can raise and an outer layer enrich.
anymodbus exceptions are translated to this hierarchy at a single boundary
in the Modbus client, always with raise ... from exc (design §4.6).
Retrying. Each class states whether retrying the same call can help. The library itself retries only reads (design §4.5); writes and operation commands are never retried automatically, because a lost reply does not mean the write failed (design §6.4).
MRO caution. Where a class belongs to two branches (a Modbus timeout is
also a transport timeout; a missing sink extra is also a configuration
problem), the extra base is a plain marker: every class shares the single
:meth:FujiError.__init__ and none defines __slots__, so the MRO stays
unambiguous and :meth:~FujiError.with_context round-trips through it.
ErrorContext
dataclass
¶
ErrorContext(
command_name=None,
protocol=None,
port=None,
address=None,
channel=None,
register_address=None,
function_code=None,
request=None,
response=None,
elapsed_s=None,
extra=_empty_extra(),
)
Structured context attached to every :class:FujiError.
Fields are best-effort — missing data is None rather than raising.
protocol and channel are typed as str so they accept the
library's ProtocolKind and ChannelId string enums as well as plain
strings. register_address is the 0-based on-the-wire address, not the
30001/40001-based register number.
extra accepts any Mapping and is always frozen into a read-only
:class:types.MappingProxyType at construction so the shared empty
sentinel can never be mutated through error.context.extra[k] = v.
merged ¶
Return a new context with updates overlaid. Unknown keys go to extra.
Source code in src/fujilib/errors.py
FujiAnalyzerStateError ¶
Bases: FujiError
What the analyzer is doing forbids the write or command now; nothing was written.
Raised after reading the analyzer's status and before any write (design §6.1): a calibration is running, the front panel shows a menu, or the analyzer reports an error that makes a calibration meaningless. Retryable once the analyzer is back on the measurement screen.
Source code in src/fujilib/errors.py
FujiCapabilityError ¶
Bases: FujiError
The operation is not available on this analyzer, model or option.
Raised before any I/O once a capability is known to be UNSUPPORTED
(design §6.6). Not retryable until reprobe().
Source code in src/fujilib/errors.py
FujiConfigurationError ¶
Bases: FujiError
Configuration-level error: bad arguments or conflicting settings.
Not retryable: the call itself has to change. A ValueError escaping
anymodbus is a fujilib bug and also surfaces here (design §4.4).
Source code in src/fujilib/errors.py
FujiConfirmationRequiredError ¶
Bases: FujiConfigurationError
An operation above SafetyTier.READ_ONLY was attempted without confirm=True.
Raised before any I/O (design §6.1). Retry only by passing
confirm=True deliberately.
Source code in src/fujilib/errors.py
FujiConnectionError ¶
Bases: FujiTransportError
The port could not be opened, or the connection was lost.
Retryable only after the device is reopened.
Source code in src/fujilib/errors.py
FujiDecodeError ¶
Bases: FujiProtocolError
A register value was received intact but does not decode.
Examples: a BCD digit above 9, an enum value the manual does not define.
Not retryable. Distinct from :class:FujiConfigurationError (design §4.4).
Source code in src/fujilib/errors.py
FujiError ¶
Bases: Exception
Base class for every :mod:fujilib exception.
Carries a typed :class:ErrorContext. The message is the human-readable
summary; the context is the machine-readable detail.
Source code in src/fujilib/errors.py
with_context ¶
Return a copy of this error with its context updated.
Useful when an inner layer raises and an outer layer wants to enrich
the context (for instance adding port or elapsed_s).
Source code in src/fujilib/errors.py
FujiFirmwareError ¶
Bases: FujiCapabilityError
The operation needs firmware the analyzer does not have.
For example, the calibration log needs firmware 2.24 or later. Not retryable.
Source code in src/fujilib/errors.py
FujiFrameError ¶
Bases: FujiProtocolError
Bad CRC, wrong length or malformed framing.
Usually link noise. Reads are retried by the client; writes are not.
Source code in src/fujilib/errors.py
FujiModbusError ¶
Bases: FujiProtocolError
A Modbus exception response or other Modbus-layer failure.
__cause__ preserves the original anymodbus exception.
Source code in src/fujilib/errors.py
FujiModbusIllegalDataAddressError ¶
Bases: FujiModbusError, FujiProtocolUnsupportedError
Modbus exception 02 — the address is outside the analyzer's map.
For a well-formed capability probe this marks the capability
UNSUPPORTED (design §6.6). Not retryable.
Source code in src/fujilib/errors.py
FujiModbusIllegalDataValueError ¶
Bases: FujiModbusError
Modbus exception 03 — illegal data value.
The manual describes it as "too many words requested / outside the map"; the bench unit also returns it for a read that crosses a region end (design §2.2). Not retryable.
Source code in src/fujilib/errors.py
FujiModbusIllegalFunctionError ¶
Bases: FujiModbusError, FujiProtocolUnsupportedError
Modbus exception 01 — the function code is not implemented.
The bench unit answers FC01 and FC02 with exception 02 instead (design §2.2). Not retryable.
Source code in src/fujilib/errors.py
FujiModbusTimeoutError ¶
Bases: FujiModbusError, FujiTimeoutError
No reply arrived within the request timeout.
A bad CRC, a wrong station number or an over-long inter-byte gap all produce no reply (design §2.2). Reads are retried by the client and each retry is counted (design §4.5); writes are not.
Source code in src/fujilib/errors.py
FujiProtocolError ¶
Bases: FujiError
Protocol-level error: framing, decoding, or an unexpected reply.
Source code in src/fujilib/errors.py
FujiProtocolUnsupportedError ¶
Bases: FujiProtocolError
The analyzer does not support this request at all. Not retryable.
Source code in src/fujilib/errors.py
FujiResyncRequiredError ¶
Bases: FujiTransportError
The port is still discarding a possible late reply after a cancellation.
New requests are refused until resynchronization completes (design §4.2); retry after it has.
Source code in src/fujilib/errors.py
FujiSinkDependencyError ¶
Bases: FujiSinkError, FujiConfigurationError
A sink's optional backing library is not installed.
Also a :class:FujiConfigurationError, because a missing extra is a
configuration problem from the caller's point of view. Not retryable until
the extra is installed.
Source code in src/fujilib/errors.py
FujiSinkError ¶
FujiSinkSchemaError ¶
Bases: FujiSinkError
A batch's shape is incompatible with the sink's locked schema. Not retryable.
Source code in src/fujilib/errors.py
FujiSinkWriteError ¶
Bases: FujiSinkError
The backing store rejected a write.
__cause__ preserves the backend's exception; whether a retry can help
depends on it.
Source code in src/fujilib/errors.py
FujiTimeoutError ¶
Bases: FujiTransportError
A transaction timed out, or a per-call operation deadline expired.
For a deadline, the context carries the operation name and the elapsed
time (design §4.6, §6.4). Reads may be retried. A write that timed out
raises :class:FujiWriteOutcomeUnknownError instead.
Source code in src/fujilib/errors.py
FujiTransportError ¶
Bases: FujiError
I/O-layer error from the serial transport or the Modbus bus.
Source code in src/fujilib/errors.py
FujiValidationError ¶
Bases: FujiConfigurationError
A request failed validation before any I/O.
Examples: an unknown parameter name, a channel or range that does not exist, a value outside its raw limits. Not retryable.
Source code in src/fujilib/errors.py
FujiVerificationError ¶
Bases: FujiProtocolError
The read-back after a write did not match the value written.
The context carries the expected and observed values. Not retryable: the front panel may have changed the setting in between (design §6.3).
Source code in src/fujilib/errors.py
FujiWriteOutcomeUnknownError ¶
Bases: FujiTimeoutError
A write request was sent but its outcome could not be established.
The analyzer may have applied the write even though the reply was lost
(design §6.4). Not retryable: read the setting back and decide. The
context's extra records the write_state, whether transmission
started, and any observed value.