View Source Ash.Error (ash v2.21.12)

Tools and utilities used by Ash to manage and conform errors

Summary

Functions

A utility to flatten a list, but preserve keyword list elements

Converts a combination of a module and json input into an Ash exception.

Converts a term into an Ash Error.

Conforms a term into one of the built-in Ash Error classes.

Types

@type class_error() :: %{
  :__struct__ => class_module(),
  :__exception__ => true,
  :class => error_class(),
  :path => [atom() | integer()],
  :changeset => Ash.Changeset.t() | nil,
  :query => Ash.Query.t() | nil,
  :error_context => [String.t()],
  :vars => Keyword.t(),
  :stacktrace => Ash.Error.Stacktrace.t() | nil,
  optional(atom()) => any()
}
@type class_module() ::
  Ash.Error.Forbidden
  | Ash.Error.Framework
  | Ash.Error.Invalid
  | Ash.Error.Unknown
@type error_class() :: :forbidden | :invalid | :framework | :unknown
@type t() :: %{
  :__struct__ => module(),
  :__exception__ => true,
  :class => error_class(),
  :path => [atom() | integer()],
  :changeset => Ash.Changeset.t() | nil,
  :query => Ash.Query.t() | nil,
  :error_context => [String.t()],
  :vars => Keyword.t(),
  :stacktrace => Ash.Error.Stacktrace.t() | nil,
  optional(atom()) => any()
}

Functions

Link to this function

choose_error(errors, changeset_or_query_or_input \\ nil)

View Source
Link to this function

clear_stacktraces(error)

View Source
Link to this function

error_descriptions(errors)

View Source
Link to this function

error_messages(errors, custom_message, stacktraces? \\ true)

View Source
Link to this function

flatten_preserving_keywords(list)

View Source

A utility to flatten a list, but preserve keyword list elements

Converts a combination of a module and json input into an Ash exception.

This is necessary for certain data layers to be able to encode and decode Ash exceptions from structs.

Link to this function

to_ash_error(list, stacktrace \\ nil, opts \\ [])

View Source

Converts a term into an Ash Error.

The term could be a simple string, the second element in an {:error, error} tuple, an Ash Error, or a list of any of these. In most cases the returned error is an Ash.Error.Unknown.UnknownError.

A stacktrace is added to the error, and any existing stacktrace (i.e. when the term is an Ash Error) is preserved.

to_ash_error converts string(s) into UnknownError(s):

  iex(1)> Ash.Error.to_ash_error("whoops!", nil, error_context: "some context")
  %Ash.Error.Unknown.UnknownError{
    changeset: nil,
    class: :unknown,
    error: "whoops!",
    error_context: ["some context"],
    field: nil,
    path: [],
    query: nil,
    stacktrace: #Stacktrace<>,
    vars: []
  }

  iex(2)> Ash.Error.to_ash_error(["whoops!", "whoops, again!!"], nil, error_context: "some context")
  [
    %Ash.Error.Unknown.UnknownError{
      changeset: nil,
      class: :unknown,
      error: "whoops!",
      error_context: ["some context"],
      field: nil,
      path: [],
      query: nil,
      stacktrace: #Stacktrace<>,
      vars: []
    },
    %Ash.Error.Unknown.UnknownError{
      changeset: nil,
      class: :unknown,
      error: "whoops, again!!",
      error_context: ["some context"],
      field: nil,
      path: [],
      query: nil,
      stacktrace: #Stacktrace<>,
      vars: []
    }
  ]

to_ash_error can preserve error-like data from a keyword-list and accumulate context if called against an Ash Error:

  iex(1)> err = Ash.Error.to_ash_error([vars: [:some_var], message: "whoops!"], nil, error_context: " some context")
  %Ash.Error.Unknown.UnknownError{
    changeset: nil,
    class: :unknown,
    error: "whoops!",
    error_context: ["some context"],
    field: nil,
    path: [],
    query: nil,
    stacktrace: #Stacktrace<>,
    vars: [:some_var]
  }
  iex(2)> Ash.Error.to_ash_error(err, nil, error_context: "some higher context")
  %Ash.Error.Unknown.UnknownError{
    changeset: nil,
    class: :unknown,
    error: "whoops!",
    error_context: ["some higher context", "some context"],
    field: nil,
    path: [],
    query: nil,
    stacktrace: #Stacktrace<>,
    vars: [:some_var]
  }

Options:

  • error_context: a sting message providing extra context around the error
Link to this function

to_error_class(values, opts \\ [])

View Source

Conforms a term into one of the built-in Ash Error classes.

The provided term would usually be an Ash Error or a list of Ash Errors.

If the term is:

  • a map/struct/Ash Error with a key :class having a value :special,
  • a list with a single map/struct/Ash Error element as above, or
  • an Ash.Error.Invalid containing such a list in its :errors field

then the term is returned unchanged.

Example:


iex(1)> Ash.Error.to_error_class("oops", changeset: Ash.Changeset.new(%Post{}), error_context: "some context")
  %Ash.Error.Unknown{
    changeset: #Ash.Changeset<
      errors: [
        %Ash.Error.Unknown.UnknownError{
          changeset: nil,
          class: :unknown,
          error: "oops",
          error_context: ["some context"],
          field: nil,
          path: [],
          query: nil,
          stacktrace: #Stacktrace<>,
          vars: []
        }
      ],
      ...
    >,
    class: :unknown,
    error_context: ["some context"],
    errors: [
      %Ash.Error.Unknown.UnknownError{
        changeset: nil,
        class: :unknown,
        error: "oops",
        error_context: ["some context"],
        field: nil,
        path: [],
        query: nil,
        stacktrace: #Stacktrace<>,
        vars: []
      }
    ],
    stacktrace: #Stacktrace<>,
    vars: []
  }

Example of nested errors:

  iex(1)> error1 = Ash.Error.to_ash_error("whoops!", nil, error_context: "some context")
  iex(2)> error2 = Ash.Error.to_ash_error("whoops, again!!", nil, error_context: "some other context")
  iex(3)> Ash.Error.to_error_class([error1, error2], error_context: "some higher context")
  %Ash.Error.Unknown{
    changeset: nil,
    class: :unknown,
    error_context: ["some higher context"],
    errors: [
      %Ash.Error.Unknown.UnknownError{
        changeset: nil,
        class: :unknown,
        error: "whoops!",
        error_context: ["some higher context", "some context"],
        field: nil,
        path: [],
        query: nil,
        stacktrace: #Stacktrace<>,
        vars: []
      },
      %Ash.Error.Unknown.UnknownError{
        changeset: nil,
        class: :unknown,
        error: "whoops, again!!",
        error_context: ["some higher context", "some other context"],
        field: nil,
        path: [],
        query: nil,
        stacktrace: #Stacktrace<>,
        vars: []
      }
    ],
    path: [],
    query: nil,
    stacktrace: #Stacktrace<>,
    vars: []
  }

Options:

  • changeset: a changeset related to the error
  • query: a query related to the error
  • error_context: a sting message providing extra context around the error