Raised when a session handle cannot be used for an operation.
The :reason field is the stable machine-readable failure contract:
:not_ownermeans a structurally valid session handle was used outside the process named by its owner PID, whether the session is live, closed, or its owner has exited. Its exact message is"Session is owned by another process".:closedmeans the owner tried to use a session it has already closed. Its exact message is"Session is closed".:unknownmeans the value is not a known owner-local session handle. Legacy bare references from Decibel 0.2, malformed values, and well-shaped owner-local handles without stored state use this reason. Its exact message is"Unknown Decibel session".:wrong_phasemeans the session is live, but the operation is not valid for the current handshake turn or transport phase. Its exact message is"Session operation <operation> requires <expected_phase> phase; current phase is <actual_phase>", with the bracketed values replaced by the corresponding atoms.
Validation first checks the handle shape, then compares its owner PID with
the calling process, then performs the owner-local state lookup, and finally
validates the phase. Consequently, a structurally valid handle used from
another process reports :not_owner before Decibel considers whether owner-
local state exists or was closed. This includes a handle retained after its
owner exits and a genuine-looking foreign handle.
This owner-PID-only classification is deliberate. Session handles are opaque and must not be constructed or altered by callers. Decibel intentionally has no handle registry, issuance proof, signature, or global verification state.
For :wrong_phase, :operation, :expected_phase, and :actual_phase
identify the rejected transition. Those fields are nil for all other
reasons.
Summary
Types
@type phase() :: :handshake_write | :handshake_read | :transport
The phase or handshake turn of a live session.
@type reason() :: :not_owner | :closed | :unknown | :wrong_phase
The reason a session operation was rejected.