harnais_error v0.1.0 Harnais.Error.Status exception View Source

Harnais.Error.Status manages an ordered collection of {:ok, value} and {:error, error} results.

Harnais.Error.Status is an Exception and supports the usual exception/1 and message/1 callbacks.

The module supports overriding the default message/1 function - see message/1 and the :message_function field.

The module supports also exporting its results (see export/1). The default exporter can be overriden - see the :export_function field.

See Harnais.Error for an overview and explanation of other documentation terms.

Documentation Terms

In the documentation these terms, usually in italics, are used to mean the same thing.

status

An instance of the module’s struct.

error and errors

An instance of an Exception struct, often Harnais.Error.

A errors is a list of error

ok and oks

An ok is any valid term. An oks is a list of ok.

result and results

A result is either {:ok, value} or {:error, error} where error is an Exception.

A results is a list of result.

Module State

The module holds it state is a struct with the following fields:

FieldPurpose
:entriesthe list of results
:message_functionSee Harnais.Error
:message_configSee Harnais.Error
:export_functionSee Harnais.Error
:export_configSee Harnais.Error

Link to this section Summary

Functions

Bang function for add_entries/2

Bang function for add_entry/2

add_error/2 adds a single error to the existing results

Bang function for add_error/2

add_errors/2 adds a list of errors to the existing results

add_ok/2 adds a single ok value to the existing results

Bang function for add_ok/2

add_oks/2 adds a list of oks to the existing results

Bang function for add_oks/2

add_results/2 adds new results to the existing results

empty?/1 returns true if the status has no results, else false

Callback implementation for Exception.exception/1

export/1 takes an instance of the module’s struct and exports it

Bang function for export/1

get_errors/2 returns {:ok, errors}

Bang function for get_errors/1

get_last_error/2 returns the last ok result in the results

get_last_error_result/2 returns a the last {:ok, value} tuple in the results

get_last_ok/1 returns {:ok, ok} where ok is the last ok

Bang function for get_last_ok/1

get_last_ok_result/2 returns {:ok, result} where result is the last ok result

get_last_result/2 returns a the last {:ok, value} or {:error, value} tuple in the results

get_oks/2 returns {:ok, oks}

Bang function for get_oks/1

get_results/1 returns the complete collection of results as {:ok, results}

Bang function for get_results/1

has_errors?/1 returns true if the status has any :ok results, else false

has_oks?/1 returns true if the status has any :ok results, else false

has_errors?/1 returns true if the status has any results, else false

message/1 is the standard Exception callback

new/1 creates a new instance of the status exception, returning {:ok, status}

new!/1 calls new/1 and, if the result is {:ok, instance} returns the instance

reset/1 reinitialised the status

Bang function for reset/1

size/1 returns the number of results in the status

update/2 takes an instance of the module’s struct and an optional opts

update!/2 calls update/2 and, if the result is {:ok, instance} returns the instance

Link to this section Types

Link to this type errors() View Source
errors() :: [error()]
Link to this type results() View Source
results() :: [result()]
Link to this type t() View Source
t() :: %Harnais.Error.Status{
  __exception__: term(),
  entries: term(),
  export_config: term(),
  export_function: term(),
  message_config: term(),
  message_function: term()
}

Link to this section Functions

Link to this function add_entries!(t, entries) View Source

Bang function for add_entries/2

Bang function for add_entry/2

Link to this function add_error(t, error) View Source
add_error(t(), error()) :: {:ok, t()} | {:error, error()}

add_error/2 adds a single error to the existing results.

Examples

iex> {:ok, status} = new!() |> add_error(42)
...> status |> get_results!
...> |> List.first |> elem(1) |> Exception.message
"42"

Bang function for add_error/2

Link to this function add_errors(t, results) View Source
add_errors(t(), errors()) :: {:ok, t()} | {:error, error()}

add_errors/2 adds a list of errors to the existing results.

Examples

iex> new!(add_errors: [42, :got_an_error, :good_one])
...> |> export!
[error: [[v: 42]], error: [[v: :got_an_error]], error: [[v: :good_one]]]

Bang function for add_errors/2

Link to this function add_ok(t, ok) View Source
add_ok(t(), ok()) :: {:ok, t()} | {:error, error()}

add_ok/2 adds a single ok value to the existing results.

Examples

iex> {:ok, status} = new!() |> add_ok(42)
...> status |> export!
[ok: 42]

Bang function for add_ok/2

Link to this function add_oks(t, values) View Source
add_oks(t(), oks()) :: {:ok, t()} | {:error, error()}

add_oks/2 adds a list of oks to the existing results.

Examples

iex> new!(add_oks: [42, :got_an_error, :good_one])
...> |> export!
[ok: 42, ok: :got_an_error, ok: :good_one]

Bang function for add_oks/2

Link to this function add_result(t, result) View Source
add_result(t(), result()) :: {:ok, t()} | {:error, error()}

add_result/2 calls add_results/2 with the List.wrap/1-ed result.

Examples

iex> {:ok, t} = new!()
...> |> add_result!({:ok, 42})
...> |> add_result!(:error)
...> |> add_result(:ok)
...> t |> get_results!
...> |> Enum.map(fn
...>    {:ok, _} = result -> result
...>    {:error, error} -> {:error, error |> Exception.message}
...> end)
[ok: 42, error: ":error", ok: :ok]

Bang function for add_result/2

Link to this function add_results(t, results \\ []) View Source
add_results(t(), results()) :: {:ok, t()} | {:error, error()}

add_results/2 adds new results to the existing results.

add_results/2 normalises any {:error, value} results, creating a new Harnais.Error Exception if the value is not an Exception already.

Examples

iex> {:ok, status} = new!() |> add_results(ok: 42, error: :got_an_error, ok: :good_one)
...> status |> get_results!
...> |> Enum.map(fn
...>    {:ok, _} = result -> result
...>    {:error, error} -> {:error, error |> Exception.message}
...> end)
[ok: 42, error: ":got_an_error", ok: :good_one]

iex> new!(add_results: [ok: 42, error: :got_an_error, error: %BadMapError{term: 42}])
...> |> get_results!
...> |> Enum.map(fn
...>    {:ok, _} = result -> result
...>    {:error, error} -> {:error, error |> Exception.message}
...> end)
[ok: 42, error: ":got_an_error", error: "expected a map, got: 42"]

iex> {:ok, status} = new!() |> add_results(ok: 42, error: :got_an_error, ok: :good_one)
...> status |> export!
[ok: 42, error: [[v: :got_an_error]], ok: :good_one]

iex> {:ok, status} = new!() |> add_results(ok: 42)
...> {:ok, status} = status |> add_results(error: :got_an_error, ok: :good_one)
...> status |> export!
[ok: 42, error: [[v: :got_an_error]], ok: :good_one]
Link to this function add_results!(t, results) View Source

Bang function for add_results/2

Link to this function empty?(t) View Source
empty?(t()) :: true | false

empty?/1 returns true if the status has no results, else false.

Examples

iex> new!() |> empty?
true

iex> new!() |> add_error!(:error1) |> add_ok!(:ok1) |> empty?
false

Callback implementation for Exception.exception/1.

export/1 takes an instance of the module’s struct and exports it.

A custom arity one export function can be given in the field :export_function and will be passed the struct.

Otherwise the default export function is used which exports each entry and merges the answers.

Exporting an :ok result returns [ok: value].

If an :error entry is not either a Harnais.Error or Harnais.Error.Status, the exports calls Exception.message/1 and returns [error: message].

If the export works, {:ok, export} is returned.

Examples

This example shows the default exporter:

iex> new!(add_results: [ok: 42, error: :got_an_error, error: %BadMapError{term: 42}])
...> |> export
{:ok, [ok: 42, error: [[v: :got_an_error]], error: [[m: "expected a map, got: 42"]]]}

This custom exporter counts the :ok and :error entries:

iex> fun = fn %{entries: entries} ->
...>   entries
...>   |> case do
...>       x when is_list(x) ->
...>         x
...>         |> Enum.split_with(fn {verb,_} -> verb == :ok end)
...>         |> case do
...>              {oks,errors} -> {:ok, {oks |> length, errors |> length}}
...>            end
...>       _ -> {:ok, {0,0}}
...>     end
...> end
...> new!(
...>   export_function: fun,
...>   add_results: [ok: 42, error: :got_an_error, error: %BadMapError{term: 42}])
...> |> export
{:ok, {1, 2}}
Link to this function get_errors(t) View Source
get_errors(t()) :: result()

get_errors/2 returns {:ok, errors}.

Examples

iex> {:error, error} = new!() |> get_errors
 ...> error |> Exception.message
 "Harnais.Error.Status has no errors"

 iex> {:ok, errors} = new!()
 ...> |> add_result!({:ok, 42})
 ...> |> add_result!({:error, %BadMapError{term: 42}})
 ...> |> add_result!({:error, :got_an_error})
 ...> |> add_result!({:ok, :good_one})
 ...> |> get_errors
 ...> errors |> Enum.map(&Exception.message/1)
 ["expected a map, got: 42", ":got_an_error"]

Bang function for get_errors/1

Link to this function get_last_error(t) View Source
get_last_error(t()) :: nil | {:error, error()}

get_last_error/2 returns the last ok result in the results.

If there are no results, it returns nil.

Examples

iex> {:error, error} = new!() |> get_last_error
...> error |> Exception.message
"Harnais.Error.Status has no errors"

iex> new!()
...> |> add_result!({:ok, 42})
...> |> add_result!({:error, :got_an_error})
...> |> add_result!({:ok, :good_one})
...> |> get_last_error!
...> |> Exception.message
":got_an_error"

Bang function for get_last_error/1

Link to this function get_last_error_result(t) View Source
get_last_error_result(t()) :: nil | {:error, error()}

get_last_error_result/2 returns a the last {:ok, value} tuple in the results.

If there are no results, it returns nil.

Examples

iex> {:error, error} = new!() |> get_last_error_result
 ...> error |> Exception.message
 "Harnais.Error.Status has no errors"

 iex> {:ok, error} = new!()
 ...> |> add_result!({:ok, 42})
 ...> |> add_result!({:error, :got_an_error})
 ...> |> add_result!({:ok, :good_one})
 ...> |> get_last_error_result
 ...> error |> Exception.message
 ":got_an_error"
Link to this function get_last_error_result!(t) View Source

Bang function for get_last_error_result/1

Link to this function get_last_ok(t) View Source
get_last_ok(t()) :: result()

get_last_ok/1 returns {:ok, ok} where ok is the last ok.

Examples

iex> {:error, error} = new!() |> get_last_ok
 ...> error |> Exception.message
 "Harnais.Error.Status has no oks"

 iex> new!()
 ...> |> add_result!({:ok, 42})
 ...> |> add_result!({:error, :got_an_error})
 ...> |> add_result!({:ok, :good_one})
 ...> |> get_last_ok!
 :good_one

Bang function for get_last_ok/1

Link to this function get_last_ok_result(t) View Source
get_last_ok_result(t()) :: result()

get_last_ok_result/2 returns {:ok, result} where result is the last ok result.

Examples

iex> {:error, error} = new!() |> get_last_ok_result
...> error |> Exception.message
"Harnais.Error.Status has no oks"

iex> new!()
...> |> add_result!({:ok, 42})
...> |> add_result!({:error, :got_an_error})
...> |> add_result!({:ok, :good_one})
...> |> get_last_ok_result!
{:ok, :good_one}

Bang function for get_last_ok_result/1

Link to this function get_last_result(t) View Source
get_last_result(t()) :: nil | {:ok, ok()} | {:error, error()}

get_last_result/2 returns a the last {:ok, value} or {:error, value} tuple in the results.

If there are no results, it returns nil.

Examples

iex> {:error, error} = new!() |> get_last_result
...> error |> Exception.message
"Harnais.Error.Status has no results"

iex> new!()
...> |> add_result!({:ok, 42})
...> |> add_result!({:error, :got_an_error})
...> |> add_result!({:ok, :good_one})
...> |> get_last_result!
{:ok, :good_one}

Bang function for get_last_result/1

get_oks/2 returns {:ok, oks}.

Examples

iex> {:error, error} = new!() |> get_oks
...> error |> Exception.message
"Harnais.Error.Status has no oks"

iex> new!()
...> |> add_result!({:ok, 42})
...> |> add_result!({:error, :got_an_error})
...> |> add_result!({:ok, :good_one})
...> |> get_oks
{:ok, [42, :good_one]}

Bang function for get_oks/1

Link to this function get_results(t) View Source
get_results(t()) :: result()

get_results/1 returns the complete collection of results as {:ok, results}.

Examples

iex> {:error, error} = new!() |> get_results
...> error |> Exception.message
"Harnais.Error.Status has no results"

iex> {:ok, status} = new!() |> add_results([ok: 42, error: :got_an_error, ok: :good_one])
...> status |> export!
[ok: 42, error: [[v: :got_an_error]], ok: :good_one]

Bang function for get_results/1

Link to this function has_errors?(t) View Source
has_errors?(t()) :: true | false

has_errors?/1 returns true if the status has any :ok results, else false.

Examples

iex> new!() |> has_errors?
false

iex> new!() |> add_error!(:error1) |> add_ok!(:ok1) |> has_errors?
true
Link to this function has_oks?(t) View Source
has_oks?(t()) :: true | false

has_oks?/1 returns true if the status has any :ok results, else false.

Examples

iex> new!() |> has_oks?
false

iex> new!() |> add_error!(:error1) |> add_ok!(:ok1) |> has_oks?
true
Link to this function has_results?(t) View Source
has_results?(t()) :: true | false

has_errors?/1 returns true if the status has any results, else false.

Examples

iex> new!() |> has_results?
false

iex> new!() |> add_error!(:error1) |> add_ok!(:ok1) |> has_results?
true

message/1 is the standard Exception callback.

Examples

iex> new!() |> message
 "Harnais.Error.Status has no errors"

 iex> new!()
 ...> |> add_result!({:ok, 42})
 ...> |> add_result!({:error, :got_an_error})
 ...> |> add_result!({:ok, :good_one})
 ...> |> message
 ":got_an_error"

 iex> new!()
 ...> |> add_result!({:ok, 42})
 ...> |> add_result!({:error, :got_an_error})
 ...> |> add_result!({:ok, :good_one})
 ...> |> add_result!({:error, :another_error})
 ...> |> message
 ":got_an_error; :another_error"
Link to this function new(opts \\ []) View Source
new(any()) :: {:ok, t()} | {:error, error()}

new/1 creates a new instance of the status exception, returning {:ok, status}.

new/1 takes optional (Keyword) options (opts) where the keys can be one of the add_ functions (e.g. add_ok/2).

Examples

iex> {:ok, status} = new()
...> match?(%Harnais.Error.Status{}, status)
true

iex> {:ok, t} = new(
...>   add_result: {:ok, 42},
...>   add_error: :failed_miserably,
...>   add_ok: :worked_fine,
...>   add_errors: [:e1, :e2])
...> t |> export!
[ok: 42, error: [[v: :failed_miserably]], ok: :worked_fine, error: [[v: :e1]], error: [[v: :e2]]]
Link to this function new!(opts \\ []) View Source
new!(any()) :: t() | no_return()

new!/1 calls new/1 and, if the result is {:ok, instance} returns the instance.

Link to this function new_result(opts \\ []) View Source
new_result(opts()) :: {:error, t()} | no_return()
Link to this function reset(t) View Source
reset(t()) :: {:ok, t()} | {:error, error()}

reset/1 reinitialised the status.

Examples

iex> {:ok, status} = new!() |> reset()
...> status |> empty?
true

iex> {:ok, status} = new!() |> add_error!(:error1) |> add_ok!(:ok1) |> reset()
...> status |> size
0

size/1 returns the number of results in the status.

Examples

iex> new!() |> size
0

iex> new!() |> add_error!(:error1) |> add_ok!(:ok1) |> size
2
Link to this function update(t, opts \\ []) View Source
update(t(), opts()) :: {:ok, t()} | {:error, error()}

update/2 takes an instance of the module’s struct and an optional opts.

The opts are normalised by calling the module’s update_canonical_opts/1 and then reduced with update_field/2:

opts |> Enum.reduce(instance, fn {k,v}, s -> s |> update_field({k,v}) end)

{:ok, instance} is returned.

Link to this function update!(t, opts \\ []) View Source
update!(t(), any()) :: t() | no_return()

update!/2 calls update/2 and, if the result is {:ok, instance} returns the instance.