defmodule Errata do
# Pull in the moduledocs from the demarcated section of the README file
@external_resource Path.expand("./README.md")
@moduledoc File.read!(Path.expand("./README.md"))
|> String.split("<!-- README START -->")
|> Enum.at(1)
|> String.split("<!-- README END -->")
|> List.first()
@typedoc """
Type to represent the various kinds of Errata errors.
"""
@type error_kind :: :domain | :infrastructure | :general | nil
@typedoc """
Type to represent any kind of Errata error.
Errata errors are `Exception` structs that have additional fields to contain extra contextual
information, such as an error reason or details about the context in which the error occurred.
"""
@type error :: %{
__struct__: module(),
__exception__: true,
__errata_error__: true,
kind: Errata.error_kind(),
message: String.t() | nil,
reason: atom() | nil,
context: map() | nil,
env: Errata.Env.t()
}
@typedoc """
Type to represent Errata domain errors.
"""
@type domain_error :: %{
__struct__: module(),
__exception__: true,
__errata_error__: true,
kind: :domain,
message: String.t() | nil,
reason: atom() | nil,
context: map() | nil,
env: Errata.Env.t() | nil
}
@typedoc """
Type to represent Errata infrastructure errors.
"""
@type infrastructure_error :: %{
__struct__: module(),
__exception__: true,
__errata_error__: true,
kind: :infrastructure,
message: String.t() | nil,
reason: atom() | nil,
context: map() | nil,
env: Errata.Env.t() | nil
}
@doc """
Returns `true` if `term` is any Errata error type; otherwise returns `false`.
Allowed in guard tests.
"""
defguard is_error(term)
when is_struct(term) and
is_exception(term) and
is_map_key(term, :__errata_error__) and
:erlang.map_get(:__errata_error__, term) == true and
is_map_key(term, :kind) and
:erlang.map_get(:kind, term) in [
:domain,
:infrastructure,
:general
] and
is_map_key(term, :message) and
is_map_key(term, :reason) and
is_map_key(term, :context) and
is_map_key(term, :env)
@doc """
Returns `true` if `term` is an Errata domain error type; otherwise returns `false`.
Allowed in guard tests.
"""
defguard is_domain_error(term)
when is_error(term) and
:erlang.map_get(:kind, term) == :domain
@doc """
Returns `true` if `term` is an Errata infrastructure error type; otherwise returns `false`.
Allowed in guard tests.
"""
defguard is_infrastructure_error(term)
when is_error(term) and
:erlang.map_get(:kind, term) == :infrastructure
end