Core dispatch pipeline: lookup → middleware → validate input → invoke handler → validate output → serialize.
Every transport (HTTP Plug, in-process caller) funnels through dispatch/4,
which threads a %RpcElixir.Resolution{} through the procedure's middleware
chain and the inner pipeline. The returned resolution carries the final
outcome on its :result field, so middleware that wraps dispatch/4 can
observe and transform results uniformly.
Typed handler errors
When a handler returns {:error, reason}, the dispatcher promotes reason
to a top-level %RpcError{}:
reasonis an atom:code = reason,message = Atom.to_string(reason),details = nil. HTTP status is derived by the transport fromRpcElixir.RpcError's framework status map (falling back to a generic status).reasonis a plain map (not a struct) with:code(atom):code = reason.code,message = reason[:message] || Atom.to_string(code),details = reasonminus:codeand:message(ornilif empty). HTTP status is derived by the transport fromRpcElixir.RpcError's framework status map (falling back to a generic status).reasonis already an%RpcError{}with a non-nil:source: passed through unchanged. If:sourceisnil, it is stamped withsource: :domainbefore being returned.- Anything else (structs, tuples, keyword lists, lists, …): wrapped as
%RpcError{code: :handler_error, details: %{kind: :error, reason: inspect(reason)}}with status 500 (the default status for:handler_errorinRpcElixir.RpcError.framework_errors/0). These are framework-level "handler returned something unexpected" cases.
This contract matches the JS Error shape on the TypeScript client:
err.code, err.message, and err.details are all populated for typed
errors, and err.message shows up in stack traces and console.error.
Summary
Functions
Dispatches a procedure call against router, returning the resolution with
:result populated.
Types
@type result() :: {:ok, term()} | {:error, RpcElixir.RpcError.t()}
Final result populated on Resolution.result after dispatch.
Functions
@spec dispatch(module(), String.t(), map(), RpcElixir.Resolution.t()) :: RpcElixir.Resolution.t()
Dispatches a procedure call against router, returning the resolution with
:result populated.
- If the input resolution is already halted, it is returned as-is.
- If the procedure path is unknown, the result is set to a
:procedure_not_foundRpcErrorwithout invoking middleware. - Otherwise, the procedure's middleware chain runs around the inner pipeline. Any middleware may halt the resolution to short-circuit.