RpcElixir.Dispatcher (elixir_ts_rpc v0.0.2)

Copy Markdown View Source

Core dispatch pipeline: lookup → middleware → validate input → invoke handler → validate output → serialize.

Every transport funnels through dispatch/4 — the HTTP Plug and in-process callers alike. It threads a %RpcElixir.Resolution{} through the procedure's middleware chain and the inner pipeline. The returned resolution carries the outcome on its :result field. So middleware that wraps dispatch/4 can observe and transform results uniformly.

Typed handler errors

A handler returns {:error, reason}. The dispatcher promotes reason to a top-level %RpcError{} and stamps source: :domain unless the handler set one. Promotion never sets :status, except in the last case below.

The transport derives the status for any promoted error whose :status is nil. It reads the framework status map in RpcElixir.RpcError. Unknown codes fall back to a generic status. Return %RpcError{status: 422} from a handler to choose the status yourself.

  • reason is an atom: code = reason, message = Atom.to_string(reason), details = nil.
  • reason is a plain map (not a struct) with an atom :code: code = reason.code, message = reason[:message] || Atom.to_string(code), details = reason minus :code and :message, or nil if empty.
  • reason is already an %RpcError{} with a non-nil :source: passed through unchanged. A nil :source is stamped source: :domain.
  • Anything else — structs, tuples, keyword lists, lists: wrapped as %RpcError{code: :handler_error, details: %{kind: :error, reason: inspect(reason)}} at status 500. That is the :handler_error default in RpcElixir.RpcError.framework_errors/0. These are framework-level "handler returned something unexpected" cases.

This contract matches the JS Error shape. On the TypeScript client, a typed error populates err.code, err.message, and err.details. err.message shows up in stack traces and console.error. See Handling errors for the user-facing guide.

Summary

Types

Final result populated on Resolution.result after dispatch.

Functions

Dispatches a procedure call against router, returning the resolution with :result populated.

Types

result()

@type result() :: {:ok, term()} | {:error, RpcElixir.RpcError.t()}

Final result populated on Resolution.result after dispatch.

Functions

dispatch(router, path, raw_input, resolution)

Dispatches a procedure call against router, returning the resolution with :result populated.

  • An already-halted resolution is returned as-is.
  • An unknown path yields a :procedure_not_found RpcError. No middleware runs.
  • Otherwise the middleware chain wraps the inner pipeline. Any middleware may halt the resolution to short-circuit.