Packages

A pragmatic approach to error handling in gleam

Current section

Files

Jump to
or_error src or_error.erl
Raw

src/or_error.erl

-module(or_error).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/or_error.gleam").
-export([pretty_print/2, map/2, map_/0, bind/2, bind_/0, return/1, flatten/1, fail/2, of_result/2, is_ok/1, is_error/1, unwrap/2, lazy_unwrap/2, unwrap_panic/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, values/1]).
-export_type([error_info/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type error_info() :: {error_info, binary(), gleam@option:option(binary())}.
-file("src/or_error.gleam", 21).
-spec pretty_print_error_info(error_info()) -> binary().
pretty_print_error_info(Error_info) ->
{error_info, Error, Context} = Error_info,
Error_str = <<"error: "/utf8, Error/binary>>,
case Context of
{some, S} ->
<<<<Error_str/binary, "
context: "/utf8>>/binary, S/binary>>;
none ->
Error_str
end.
-file("src/or_error.gleam", 34).
?DOC(" A function to prettily print the or_error.\n").
-spec pretty_print({ok, DTX} | {error, error_info()}, fun((DTX) -> binary())) -> binary().
pretty_print(Or_error, Using) ->
case Or_error of
{ok, A} ->
Using(A);
{error, E} ->
pretty_print_error_info(E)
end.
-file("src/or_error.gleam", 46).
?DOC(
" The monadic map function.\n"
"\n"
" Updates a value held within the `Ok` constructor by calling the given function on it.\n"
"\n"
" If the or_error is an `Error` rather than `Ok` the function is not called and the or_error stays the same.\n"
).
-spec map({ok, DTZ} | {error, error_info()}, fun((DTZ) -> DUB)) -> {ok, DUB} |
{error, error_info()}.
map(Or_error, F) ->
case Or_error of
{ok, A} ->
{ok, F(A)};
{error, E} ->
{error, E}
end.
-file("src/or_error.gleam", 54).
?DOC(" A version of `map` for piping to for `use`.\n").
-spec map_() -> fun(({ok, DUD} | {error, error_info()}) -> fun((fun((DUD) -> DUF)) -> {ok,
DUF} |
{error, error_info()})).
map_() ->
fun(Or_error) -> fun(F) -> map(Or_error, F) end end.
-file("src/or_error.gleam", 63).
?DOC(
" The monadic bind function.\n"
"\n"
" Updates a value held within the `Ok` constructor by calling the given `OrError`-returning function on it.\n"
"\n"
" If the or_error is an `Error` rather than `Ok` the function is not called and the or_error stays the same.\n"
).
-spec bind(
{ok, DUH} | {error, error_info()},
fun((DUH) -> {ok, DUJ} | {error, error_info()})
) -> {ok, DUJ} | {error, error_info()}.
bind(Or_error, F) ->
case Or_error of
{ok, A} ->
F(A);
{error, E} ->
{error, E}
end.
-file("src/or_error.gleam", 71).
?DOC(" A version of `bind` for piping to for `use`.\n").
-spec bind_() -> fun(({ok, DUM} | {error, error_info()}) -> fun((fun((DUM) -> {ok,
DUO} |
{error, error_info()})) -> {ok, DUO} | {error, error_info()})).
bind_() ->
fun(Or_error) -> fun(F) -> bind(Or_error, F) end end.
-file("src/or_error.gleam", 78).
?DOC(
" The monad return function.\n"
"\n"
" Allows construction of an `Ok` value.\n"
).
-spec return(DUR) -> {ok, DUR} | {error, error_info()}.
return(A) ->
{ok, A}.
-file("src/or_error.gleam", 83).
?DOC(" Merges a nested `OrError` into a single layer.\n").
-spec flatten({ok, {ok, DUT} | {error, error_info()}} | {error, error_info()}) -> {ok,
DUT} |
{error, error_info()}.
flatten(Result) ->
case Result of
{ok, X} ->
X;
{error, Error} ->
{error, Error}
end.
-file("src/or_error.gleam", 96).
?DOC(
" Allows construction of an `Error` value as the `ErrorInfo` type.\n"
"\n"
" The `error` field is constructed by calling `string.inspect` on the passed error value.\n"
"\n"
" The optional `context` field is to allow developers to provide information on the error occurred.\n"
" If the empty string is passed, the context field will be set to `None`.\n"
).
-spec fail(any(), binary()) -> {ok, any()} | {error, error_info()}.
fail(E, Context) ->
Error = gleam@string:inspect(E),
Context@1 = case Context of
<<""/utf8>> ->
none;
S ->
{some, S}
end,
{error, {error_info, Error, Context@1}}.
-file("src/or_error.gleam", 107).
?DOC(
" A helper function to allow easy construction of `OrError` from a `Result`.\n"
" If the result is an `Error`, the `ErrorInfo` will be construced by `fail`.\n"
).
-spec of_result({ok, DUZ} | {error, any()}, binary()) -> {ok, DUZ} |
{error, error_info()}.
of_result(Result, Context) ->
case Result of
{ok, A} ->
{ok, A};
{error, E} ->
fail(E, Context)
end.
-file("src/or_error.gleam", 115).
?DOC(" Checks whether the or_error is an `Ok` value.\n").
-spec is_ok({ok, any()} | {error, error_info()}) -> boolean().
is_ok(Or_error) ->
case Or_error of
{ok, _} ->
true;
{error, _} ->
false
end.
-file("src/or_error.gleam", 123).
?DOC(" Checks whether the or_error is an `Error` value.\n").
-spec is_error({ok, any()} | {error, error_info()}) -> boolean().
is_error(Or_error) ->
case Or_error of
{ok, _} ->
false;
{error, _} ->
true
end.
-file("src/or_error.gleam", 131).
?DOC(" Extracts the `Ok` value from an or_error, returning a default value if the or_error is an `Error`.\n").
-spec unwrap({ok, DVI} | {error, error_info()}, DVI) -> DVI.
unwrap(Or_error, Default) ->
case Or_error of
{ok, A} ->
A;
{error, _} ->
Default
end.
-file("src/or_error.gleam", 139).
?DOC(" Extracts the `Ok` value from an or_error, evaluating the default function if the or_error is an `Error`.\n").
-spec lazy_unwrap({ok, DVK} | {error, error_info()}, fun(() -> DVK)) -> DVK.
lazy_unwrap(Or_error, Default) ->
case Or_error of
{ok, A} ->
A;
{error, _} ->
Default()
end.
-file("src/or_error.gleam", 147).
?DOC(" Extracts the `Ok` value from an or_error, panicing if the or_error is an `Error`.\n").
-spec unwrap_panic({ok, DVM} | {error, error_info()}) -> DVM.
unwrap_panic(Or_error) ->
case Or_error of
{ok, A} ->
A;
{error, E} ->
erlang:error(#{gleam_error => panic,
message => pretty_print_error_info(E),
file => <<?FILEPATH/utf8>>,
module => <<"or_error"/utf8>>,
function => <<"unwrap_panic"/utf8>>,
line => 150})
end.
-file("src/or_error.gleam", 155).
?DOC(" Returns the first value if it is Ok, otherwise returns the second value.\n").
-spec 'or'({ok, DVO} | {error, error_info()}, {ok, DVO} | {error, error_info()}) -> {ok,
DVO} |
{error, error_info()}.
'or'(First, Second) ->
case First of
{ok, _} ->
First;
{error, _} ->
Second
end.
-file("src/or_error.gleam", 163).
?DOC(" Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value.\n").
-spec lazy_or(
{ok, DVS} | {error, error_info()},
fun(() -> {ok, DVS} | {error, error_info()})
) -> {ok, DVS} | {error, error_info()}.
lazy_or(First, Second) ->
case First of
{ok, _} ->
First;
{error, _} ->
Second()
end.
-file("src/or_error.gleam", 181).
-spec to_result({ok, DWB} | {error, error_info()}) -> {ok, DWB} |
{error, error_info()}.
to_result(Or_error) ->
case Or_error of
{ok, A} ->
{ok, A};
{error, E} ->
{error, E}
end.
-file("src/or_error.gleam", 174).
?DOC(
" Combines a list of or_errors into a single or_error.\n"
"\n"
" If all elements in the list are `Ok` then returns an `Ok` holding the list of values.\n"
" If any element is `Error` then returns the first error.\n"
).
-spec all(list({ok, DVW} | {error, error_info()})) -> {ok, list(DVW)} |
{error, error_info()}.
all(Or_errors) ->
case (gleam@list:try_map(Or_errors, fun to_result/1)) of
{ok, Oks} ->
{ok, Oks};
{error, E} ->
{error, E}
end.
-file("src/or_error.gleam", 198).
-spec partition_loop(
list({ok, DWK} | {error, error_info()}),
list(DWK),
list(error_info())
) -> {list(DWK), list(error_info())}.
partition_loop(Or_errors, Oks, Errors) ->
case Or_errors of
[] ->
{Oks, Errors};
[{ok, A} | Rest] ->
partition_loop(Rest, [A | Oks], Errors);
[{error, E} | Rest@1] ->
partition_loop(Rest@1, Oks, [E | Errors])
end.
-file("src/or_error.gleam", 194).
?DOC(
" Given a list of or_errors, returns a pair where the first element is a list\n"
" of all the values inside `Ok` and the second element is a list with all the\n"
" values inside `Error`.\n"
"\n"
" The values in both lists appear in reverse order with respect to their\n"
" position in the original list of or_errors.\n"
).
-spec partition(list({ok, DWF} | {error, error_info()})) -> {list(DWF),
list(error_info())}.
partition(Or_errors) ->
partition_loop(Or_errors, [], []).
-file("src/or_error.gleam", 211).
?DOC(" Replace the value inside `Ok`. Does nothing if the or_error is an `Error`.\n").
-spec replace({ok, any()} | {error, error_info()}, DWS) -> {ok, DWS} |
{error, error_info()}.
replace(Or_error, Value) ->
case Or_error of
{ok, _} ->
{ok, Value};
{error, E} ->
{error, E}
end.
-file("src/or_error.gleam", 219).
?DOC(" Given a list of or_errors, returns only the values inside Ok.\n").
-spec values(list({ok, DWU} | {error, error_info()})) -> list(DWU).
values(Or_errors) ->
gleam@list:filter_map(Or_errors, fun to_result/1).