Decibel.SessionError exception (decibel v1.0.1)

Copy Markdown View Source

Raised when a session handle cannot be used for an operation.

The :reason field is the stable machine-readable failure contract:

  • :not_owner means 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".
  • :closed means the owner tried to use a session it has already closed. Its exact message is "Session is closed".
  • :unknown means 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_phase means 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

The phase or handshake turn of a live session.

The reason a session operation was rejected.

t()

Types

phase()

@type phase() :: :handshake_write | :handshake_read | :transport

The phase or handshake turn of a live session.

reason()

@type reason() :: :not_owner | :closed | :unknown | :wrong_phase

The reason a session operation was rejected.

t()

@type t() :: %Decibel.SessionError{
  __exception__: true,
  actual_phase: phase() | nil,
  expected_phase: phase() | nil,
  message: String.t(),
  operation: atom() | nil,
  reason: reason()
}