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".:already_handed_offmeans an accepted handshake cannot be handed off again. Its exact message is"Session was already handed off".: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 that Decibel did not issue 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,
so a constructed or altered owner-local handle may report :closed rather
than :unknown.
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 | :handshake | :transport
The phase or handshake turn of a live session.
@type reason() :: :not_owner | :closed | :already_handed_off | :unknown | :wrong_phase
The reason a session operation was rejected.