Turns an invalid changeset into error entries and a problem.
A context function reports invalid data as a changeset.
LightningWeb.API.FallbackController hands it to problem/3, which makes one
entry per error and picks the response code from the entries. Each entry
points at the part of the request it is about, such as a body key, a position
in a list, or a path segment, using the request's key names rather than the
schema's. Web code that checks the request itself builds entries with
entry/2 and returns them through refuse/1.
An entry's code comes from the error's code: option, or from Ecto's own
options. An error with neither raises. There is no fallback code.
Summary
Functions
One entry, for a producer that validates the request itself.
Every error in changeset and its children, as entries.
The error for a reference in the body that matches nothing the caller can see. Something missing and something hidden get the same error.
The 400 invalid_parameter problem for a refused changeset over a route's
query parameters, with one entry per error, each naming its parameter.
An RFC 6901 JSON Pointer in URI-fragment form: each key has ~ written
~0 and / written ~1, then the whole is percent-encoded wherever a
character isn't allowed in a fragment.
The problem for a refused changeset. The first rule that matches wins
:ok when there are no entries, otherwise a 422 invalid problem holding
them all, for a producer that checks the request itself.
{:ok, value} passed through, or {:error, changeset} over a route's query
parameters turned into its 400 invalid_parameter problem.
Types
Functions
One entry, for a producer that validates the request itself.
error is shaped as a changeset error, {message, opts}, and is coded and
interpolated the same way. location is a list of the request's keys and
positions, or {:parameter, name}, or {:header, name}, or {:path, name}
for a path segment, named by its route parameter. A path names a segment,
never carries its text.
@spec from_changeset(Ecto.Changeset.t(), %{required(atom()) => atom()}, [ {:path, [atom()]} ]) :: [ entry() ]
Every error in changeset and its children, as entries.
renames maps an Ecto field to the request's key, at any depth:
%{project_users: :members}. An error whose options carry key: is placed
there instead of at its field: one request key, or a list of the request's
keys and positions below the error's level.
path: lists the top-level request keys the request sent as path segments
rather than in its body, so their errors name the segment: path: [:key].
Raises ArgumentError for an error with no code, and for an error on a
child the request didn't send, since neither can be placed in the request.
The error for a reference in the body that matches nothing the caller can see. Something missing and something hidden get the same error.
@spec parameters(Ecto.Changeset.t()) :: LightningWeb.API.Problem.t()
The 400 invalid_parameter problem for a refused changeset over a route's
query parameters, with one entry per error, each naming its parameter.
An RFC 6901 JSON Pointer in URI-fragment form: each key has ~ written
~0 and / written ~1, then the whole is percent-encoded wherever a
character isn't allowed in a fragment.
@spec problem(Ecto.Changeset.t(), %{required(atom()) => atom()}, [{:path, [atom()]}]) :: LightningWeb.API.Problem.t()
The problem for a refused changeset. The first rule that matches wins:
- any error coded
storage_failed: 500internal, since the server failed, not the request; - any error coded
not_ready: 503not_ready, with no entries; - every error
exceeds_limit: 402exceeds_limit; - otherwise 422
invalid, without anyexceeds_limitentries.
A value in the body that must be unique and is already in use is a taken
entry in the 422 like any other problem with the body. 409 is only for the
state of the record the URL names.
@spec refuse([entry()]) :: :ok | {:error, LightningWeb.API.Problem.t()}
:ok when there are no entries, otherwise a 422 invalid problem holding
them all, for a producer that checks the request itself.
@spec refuse_parameters({:ok, value} | {:error, Ecto.Changeset.t()}) :: {:ok, value} | {:error, LightningWeb.API.Problem.t()} when value: term()
{:ok, value} passed through, or {:error, changeset} over a route's query
parameters turned into its 400 invalid_parameter problem.