Alembic v2.1.0 Alembic.Error

Error objects provide additional information about problems encountered while performing an operation. Error objects MUST be returned as an array keyed by errors in the top level of a JSON API document.

Summary

Types

The name of a JSON type in human-readable terms, such as "array" or "object"

t()

Additional information about problems encountered while performing an operation

Functions

When two or more members can’t be present at the same time

Descends source pointer to child of current source pointer

Converts a JSON object into a JSON API Error, t

When the minimum number of children are not present, give the sender a list of the children they could have sent

When a required (MUST in the spec) member is missing

Error when the JSON type of the field is wrong

Types

human_type :: String.t

The name of a JSON type in human-readable terms, such as "array" or "object".

t :: %Alembic.Error{code: String.t, detail: String.t, id: String.t, links: Alembic.Links.t, meta: Alembic.Meta.t, source: Alembic.Source.t, status: String.t, title: String.t}

Additional information about problems encountered while performing an operation.

An error object MAY have the following members:

  • code - an application-specific error code.
  • detail - a human-readable explanation specific to this occurrence of the problem.
  • id - a unique identifier for this particular occurrence of the problem.
  • links - contains the following members:

    • "about" - an Alembic.Link.link leading to further details about this particular occurrence of the problem.
  • meta - non-standard meta-information about the error.
  • source - contains references to the source of the error, optionally including any of the following members:
  • status - the HTTP status code applicable to this problem.
  • title - a short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.

Functions

conflicting(template, children)

Specs

conflicting(t, [String.t]) :: t

When two or more members can’t be present at the same time.

iex> Alembic.Error.conflicting(
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/errors/0/source"
...>     }
...>   },
...>   ~w{parameter pointer}
...> )
%Alembic.Error{
  detail: "The following members conflict with each other (only one can be present):\nparameter\npointer",
  meta: %{
    "children" => [
      "parameter",
      "pointer"
    ]
  },
  source: %Alembic.Source{
    pointer: "/errors/0/source"
  },
  status: "422",
  title: "Children conflicting"
}
descend(error, child)

Specs

descend(t, String.t | integer) :: t

Descends source pointer to child of current source pointer

iex> Alembic.Error.descend(
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/data"
...>     }
...>   },
...>   1
...> )
%Alembic.Error{
  source: %Alembic.Source{
    pointer: "/data/1"
  }
}
from_json(map, error)

Converts a JSON object into a JSON API Error, t.

iex> Alembic.Error.from_json(
...>   %{
...>     "code" => "1",
...>     "detail" => "There was an error in data",
...>     "id" => "2",
...>     "links" => %{
...>       "about" => %{
...>         "href" => "/errors/2",
...>         "meta" => %{
...>           "extra" => "about meta"
...>         }
...>       }
...>     },
...>     "meta" => %{
...>       "extra" => "error meta"
...>     },
...>     "source" => %{
...>       "pointer" => "/data"
...>     },
...>     "status" => "422",
...>     "title" => "There was an error"
...>   },
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/errors/0"
...>     }
...>   }
...> )
{
  :ok,
  %Alembic.Error{
    code: "1",
    detail: "There was an error in data",
    id: "2",
    links: %{
      "about" => %Alembic.Link{
        href: "/errors/2",
        meta: %{
          "extra" => "about meta"
        }
      }
    },
    meta: %{
      "extra" => "error meta"
    },
    source: %Alembic.Source{
      pointer: "/data"
    },
    status: "422",
    title: "There was an error"
  }
}
minimum_children(template, children)

Specs

minimum_children(t, [String.t]) :: t

When the minimum number of children are not present, give the sender a list of the children they could have sent.

iex> Alembic.Error.minimum_children(
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/data/relationships/author"
...>     }
...>   },
...>   ~w{data links meta}
...> )
%Alembic.Error{
  detail: "At least one of the following children of `/data/relationships/author` must be present:\n" <>
          "data\n" <>
          "links\n" <>
          "meta",
  meta: %{
    "children" => [
      "data",
      "links",
      "meta"
    ]
  },
  source: %Alembic.Source{
    pointer: "/data/relationships/author"
  },
  status: "422",
  title: "Not enough children"
}
missing(template, child)

Specs

missing(t, String.t) :: t

When a required (MUST in the spec) member is missing

Top-level member is missing

iex> Alembic.Error.missing(
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: ""
...>     }
...>   },
...>   "data"
...> )
%Alembic.Error{
  detail: "`/data` is missing",
  meta: %{
    "child" => "data"
  },
  source: %Alembic.Source{
    pointer: ""
  },
  status: "422",
  title: "Child missing"
}

Nested member is missing

iex> Alembic.Error.missing(
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       pointer: "/data"
...>     }
...>   },
...>   "type"
...> )
%Alembic.Error{
  detail: "`/data/type` is missing",
  meta: %{
    "child" => "type"
  },
  source: %Alembic.Source{
    pointer: "/data"
  },
  status: "422",
  title: "Child missing"
}
relationship_path(template \\ %Alembic.Error{source: %Alembic.Source{parameter: "include"}}, unknown_relationship_path)

Specs

relationship_path(t, String.t) :: t

When a relationship path in "includes" params is unknown.

If no template is given, it is assumed that the source is the “include” parameter

iex> Alembic.Error.relationship_path("secret")
%Alembic.Error{
  detail: "`secret` is an unknown relationship path",
  meta: %{
    "relationship_path" => "secret"
  },
  source: %Alembic.Source{
    parameter: "include"
  },
  title: "Unknown relationship path"
}

If using a different parameter than recommended in the JSON API spec, a template can be used

iex> Alembic.Error.relationship_path(
...>   %Alembic.Error{
...>     source: %Alembic.Source{
...>       parameter: "relationships"
...>     }
...>   },
...>   "secret"
...> )
%Alembic.Error{
  detail: "`secret` is an unknown relationship path",
  meta: %{
    "relationship_path" => "secret"
  },
  source: %Alembic.Source{
    parameter: "relationships"
  },
  title: "Unknown relationship path"
}
type(error, human_type)

Specs

type(t, human_type) :: t

Error when the JSON type of the field is wrong.

NOTE: The JSON type should be used, not the Elixir/Erlang type, so if a member is not a map in Elixir, the human_type should be "object". Likewise, if a member is not a list in Elixir, the human_type should be "array".

When member is not an Elixir list or JSON array

iex> validate_errors = fn
...>   (list) when is_list(list) ->
...>     {:ok, list}
...>   (_) ->
...>     {
...>       :error,
...>       Alembic.Error.type(
...>         %Alembic.Error{
...>           source: %Alembic.Source{
...>             pointer: "/errors"
...>           }
...>         },
...>         "array"
...>       )
...>     }
...> end
iex> json = %{"errors" => "invalid"}
iex> validate_errors.(json["errors"])
{
  :error,
  %Alembic.Error{
    detail: "`/errors` type is not array",
    meta: %{
      "type" => "array"
    },
    source: %Alembic.Source{
      pointer: "/errors"
    },
    status: "422",
    title: "Type is wrong"
  }
}

When member is not an Elixir map or JSON object

iex> validate_meta = fn
...>   (meta) when is_map(meta) ->
...>     {:ok, meta}
...>   (_) ->
...>     {
...>       :error,
...>       Alembic.Error.type(
...>         %Alembic.Error{
...>           source: %Alembic.Source{
...>             pointer: "/meta"
...>           }
...>         },
...>         "object"
...>       )
...>     }
...> end
iex> json = %{"meta" => "invalid"}
iex> validate_meta.(json["meta"])
{
  :error,
  %Alembic.Error{
    detail: "`/meta` type is not object",
    meta: %{
      "type" => "object"
    },
    source: %Alembic.Source{
      pointer: "/meta"
    },
    status: "422",
    title: "Type is wrong"
  }
}