Malachi. HTTP. Problem
(malachi v0.22.7)
View Source
The one error shape of every HTTP surface, the legacy dashboard (Malachi.Dashboard) and the console
(Malachi.Console.Router): an RFC 9457 application/problem+json body whose type is a translation
key and whose data travel in extension members, as section 10.3 of
docs/design/operator-interfaces.md sets. The body carries no title or detail: Malachi.I18n.locale/0
is node global, so a phrase translated here would come out in the node's language rather than the
operator's, and the client translates the key itself.
from_error/1 is the single map from an error a handler meets to its status, key and members, so two
endpoints meeting the same error answer it the same way. build/2 and for_error/1 are pure and
return the status, the headers and the encoded body, which each endpoint frames with its own transport.
Example
iex> {status, type, members} = Malachi.HTTP.Problem.from_error({:missing_role, :editor, :viewer})
iex> {status, type, members}
{403, "errors.auth.missing_role", %{"required_role" => "editor", "role" => "viewer"}}
Summary
Functions
The response for type with extension members, as {status, headers, body}. The status comes from
types/0, so a key and its status cannot disagree. Headers are the content type plus what the status
obliges: WWW-Authenticate on a 401 and Retry-After (whole seconds, rounded up) on a 429 that carries
retry_after_ms. Raises on a key that is not in types/0, which a test meets before a client does.
build/2 for the error from_error/1 classifies.
The status, translation key and extension members for an error a handler met. Covers the session and
role refusals of Malachi.Console.Access, the user and ACL writes of Malachi.Auth, a machine version
refusal (Malachi.Cluster.MachineVersion.refusal?/1) and the policy refusals of Malachi.Policies.
Anything else is a control plane that did not answer usefully, a 503 the same request may pass later.
The status type is answered with.
Every translation key a problem response can carry, mapped to its HTTP status.
Types
Functions
The response for type with extension members, as {status, headers, body}. The status comes from
types/0, so a key and its status cannot disagree. Headers are the content type plus what the status
obliges: WWW-Authenticate on a 401 and Retry-After (whole seconds, rounded up) on a 429 that carries
retry_after_ms. Raises on a key that is not in types/0, which a test meets before a client does.
@spec for_error(term()) :: {pos_integer(), [{String.t(), String.t()}], binary()}
build/2 for the error from_error/1 classifies.
@spec from_error(term()) :: {pos_integer(), type(), map()}
The status, translation key and extension members for an error a handler met. Covers the session and
role refusals of Malachi.Console.Access, the user and ACL writes of Malachi.Auth, a machine version
refusal (Malachi.Cluster.MachineVersion.refusal?/1) and the policy refusals of Malachi.Policies.
Anything else is a control plane that did not answer usefully, a 503 the same request may pass later.
@spec status(type()) :: pos_integer()
The status type is answered with.
@spec types() :: %{required(type()) => pos_integer()}
Every translation key a problem response can carry, mapped to its HTTP status.