Zoi.Error exception (Zoi v0.10.7)

View Source

Represents a validation error with detailed information.

Fields

  • code: Error code
  • issue: A tuple with the message and keyword with error variables.
  • message: Description of the error, formed from the issue message and variables.
  • path: A list representing the path to the location of the error.

Errors

All Zoi errors have a code that can be used to identify the type of error. The following error codes are defined:

  • :invalid_type
  • :invalid_literal
  • :invalid_tuple
  • :unrecognized_key
  • :invalid_enum_value
  • :not_in_values
  • :required
  • :less_than
  • :greater_than
  • :less_than_or_equal_to
  • :greater_than_or_equal_to
  • :invalid_length
  • :invalid_format
  • :custom

Example

The error struct follows this format:

%Zoi.Error{
  code: :invalid_type,
  issue: {"invalid type: expected string", [type: :string]},
  message: "invalid type: expected string",
  path: [:user, :name]
}

The :message field is generated by replacing the placeholders in the :issue message. This allows for dynamic error messages that provide context about the validation failure and possibility for localization using Gettext or similar libraries. Usually the issue and message will share the same content, but the issue retains the original template and variables for further processing if needed.

This module is mostly used internally, but can be useful if need to use the built-in error types or create custom errors.

Summary

Types

The path to the location of the error.

t()

Error struct containing detailed information about a validation error.

Functions

Creates a custom error with the given options.

Creates a greater than error for the given type and minimum value.

Creates a greater than or equal to error for the given type and minimum value.

Creates an invalid format error for the given ending string.

Creates an invalid enum value error for the given enum values.

Creates an invalid format error for the given regex pattern.

Creates an invalid length error for the given type and length.

Creates an invalid literal error for the expected value.

Creates an invalid format error for the given starting string.

Creates an invalid tuple error for the expected and actual lengths.

Creates an invalid type error for the expected type.

Creates a less than error for the given type and maximum value.

Creates a less than or equal to error for the given type and maximum value.

Creates a new Zoi.Error struct.

Creates a not in values error for the given list of valid values.

Prepends a path to the error's existing path.

Creates a required error for the given key.

Creates an unrecognized key error for the given key.

Types

error_opts()

@type error_opts() :: [
  code: atom(),
  issue: {binary(), keyword()} | nil,
  message: binary(),
  path: path()
]

path()

@type path() :: [atom() | binary() | integer()]

The path to the location of the error.

t()

@type t() :: %Zoi.Error{
  __exception__: true,
  code: atom(),
  issue: {binary(), keyword()} | nil,
  message: binary(),
  path: path()
}

Error struct containing detailed information about a validation error.

Functions

custom_error(opts \\ [])

@spec custom_error(opts :: error_opts()) :: t()

Creates a custom error with the given options.

Example

iex> Zoi.Error.custom_error(issue: {"error %{num}", [num: 404]})
%Zoi.Error{
  code: :custom,
  issue: {"error %{num}", [num: 404]},
  message: "error 404",
  path: []
}

greater_than(type, min, opts \\ [])

@spec greater_than(:array | :number | :date, any(), keyword()) :: t()

Creates a greater than error for the given type and minimum value.

Example

iex> Zoi.Error.greater_than(:number, 5)
%Zoi.Error{
  code: :greater_than,
  issue: {"too small: must be greater than %{count}", [count: 5]},
  message: "too small: must be greater than 5"
}

greater_than_or_equal_to(type, min, opts \\ [])

@spec greater_than_or_equal_to(:string | :array | :number | :date, any(), keyword()) ::
  t()

Creates a greater than or equal to error for the given type and minimum value.

Example

iex> Zoi.Error.greater_than_or_equal_to(:string, 3)
%Zoi.Error{
  code: :greater_than_or_equal_to,
  issue: {"too small: must have at least %{count} character(s)", [count: 3]},
  message: "too small: must have at least 3 character(s)"
}

invalid_ending_string(suffix, opts \\ [])

@spec invalid_ending_string(
  binary(),
  keyword()
) :: t()

Creates an invalid format error for the given ending string.

Example

iex> Zoi.Error.invalid_ending_string(".com")
%Zoi.Error{
  code: :invalid_format,
  issue: {"invalid format: must end with '%{value}'", [value: ".com"]},
  message: "invalid format: must end with '.com'"
}

invalid_enum_value(enum, opts \\ [])

Creates an invalid enum value error for the given enum values.

Example

iex> Zoi.Error.invalid_enum_value([{:a, "apple"}, {:b, "banana"}, {:c, "cherry"}])
%Zoi.Error{
  code: :invalid_enum_value,
  issue: {"invalid enum value: expected one of %{values}", [type: :enum, values: "apple, banana, cherry"]},
  message: "invalid enum value: expected one of apple, banana, cherry"
}

invalid_format(pattern, opts \\ [])

@spec invalid_format(
  Regex.t(),
  keyword()
) :: t()

Creates an invalid format error for the given regex pattern.

Example

iex> %Zoi.Error{} = error = Zoi.Error.invalid_format(~r/^[^a-z]*$/, format: :upcase)
iex> error.code
:invalid_format
iex> {msg, opts} = error.issue
iex> msg
"invalid format: must match pattern %{pattern}"
iex> Regex.source(opts[:pattern])
"^[^a-z]*$"
iex> opts[:format]
:upcase
iex> error.message
"invalid format: must match pattern ^[^a-z]*$"

invalid_length(type, length, opts \\ [])

@spec invalid_length(:string | :array, non_neg_integer(), keyword()) :: t()

Creates an invalid length error for the given type and length.

Example

iex> Zoi.Error.invalid_length(:string, 5)
%Zoi.Error{
  code: :invalid_length,
  issue: {"invalid length: must have %{count} character(s)", [count: 5]},
  message: "invalid length: must have 5 character(s)"
}

invalid_literal(value, opts \\ [])

Creates an invalid literal error for the expected value.

Example

iex> Zoi.Error.invalid_literal(42)
%Zoi.Error{
  code: :invalid_literal,
  issue: {"invalid literal: expected %{expected}", [expected: 42]},
  message: "invalid literal: expected 42"
}

invalid_starting_string(prefix, opts \\ [])

@spec invalid_starting_string(
  binary(),
  keyword()
) :: t()

Creates an invalid format error for the given starting string.

Example

iex> Zoi.Error.invalid_starting_string("http")
%Zoi.Error{
  code: :invalid_format,
  issue: {"invalid format: must start with '%{value}'", [value: "http"]},
  message: "invalid format: must start with 'http'"
}

invalid_tuple(expected_length, actual_length, opts \\ [])

@spec invalid_tuple(non_neg_integer(), non_neg_integer(), keyword()) :: t()

Creates an invalid tuple error for the expected and actual lengths.

Example

iex> Zoi.Error.invalid_tuple(3, 5)
%Zoi.Error{
  code: :invalid_tuple,
  issue: {"invalid tuple: expected length %{expected_length}, got %{actual_length}", [expected_length: 3, actual_length: 5]},
  message: "invalid tuple: expected length 3, got 5"
}

invalid_type(type, opts \\ [])

Creates an invalid type error for the expected type.

Example

iex> Zoi.Error.invalid_type(:string)
%Zoi.Error{
  code: :invalid_type,
  issue: {"invalid type: expected string", [type: :string]},
  message: "invalid type: expected string"
}

invalid_url(url, opts \\ [])

less_than(type, max, opts \\ [])

@spec less_than(:array | :number | :date, any(), keyword()) :: t()

Creates a less than error for the given type and maximum value.

Example

iex> Zoi.Error.less_than(:number, 10)
%Zoi.Error{
  code: :less_than,
  issue: {"too big: must be less than %{count}", [count: 10]},
  message: "too big: must be less than 10"
}

less_than_or_equal_to(type, max, opts \\ [])

@spec less_than_or_equal_to(:string | :array | :number | :date, any(), keyword()) ::
  t()

Creates a less than or equal to error for the given type and maximum value.

Example

iex> Zoi.Error.less_than_or_equal_to(:string, 10)
%Zoi.Error{
  code: :less_than_or_equal_to,
  issue: {"too big: must have at most %{count} character(s)", [count: 10]},
  message: "too big: must have at most 10 character(s)"
}

new(opts \\ [])

@spec new(error_opts() | map()) :: t()

Creates a new Zoi.Error struct.

not_in_values(values, opts \\ [])

Creates a not in values error for the given list of valid values.

Example

iex> Zoi.Error.not_in_values(["red", "green", "blue"])
%Zoi.Error{
  code: :not_in_values,
  issue: {"invalid value: expected one of %{values}", [values: ["red", "green", "blue"]]},
  message: "invalid value: expected one of red, green, blue",
  path: []
}

prepend_path(error, path)

@spec prepend_path(t(), any()) :: t()

Prepends a path to the error's existing path.

Example

iex> error = Zoi.Error.invalid_type(:string, path: [:name])
iex> error = Zoi.Error.prepend_path(error, [:user])
iex> error.path
[:user, :name]

required(key, opts \\ [])

Creates a required error for the given key.

Example

iex> Zoi.Error.required(:name)
%Zoi.Error{
  code: :required,
  issue: {"is required", [key: :name]},
  message: "is required"
}

unrecognized_key(key)

@spec unrecognized_key(atom() | binary() | integer()) :: t()

Creates an unrecognized key error for the given key.

Example

iex> Zoi.Error.unrecognized_key(:foo)
%Zoi.Error{
  code: :unrecognized_key,
  issue: {"unrecognized key: '%{key}'", [key: :foo]},
  message: "unrecognized key: 'foo'"
}