0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Aggregate validation errors and pass them in exception

This commit is contained in:
Loïc Hoguin 2017-07-01 16:10:27 +02:00
parent 2bcb390257
commit 5a272e4fbe
No known key found for this signature in database
GPG key ID: 71366FF21851DF03

View file

@ -762,28 +762,46 @@ kvlist_to_map(Keys, [{Key, Value}|Tail], Map) ->
kvlist_to_map(Keys, Tail, Map) kvlist_to_map(Keys, Tail, Map)
end. end.
%% Loop through fields, if value is missing and no default, crash; filter(Fields, Map0) ->
%% else if value is missing and has a default, set default; case filter(Fields, Map0, #{}) of
%% otherwise apply constraints. If constraint fails, crash. {ok, Map} ->
filter([], Map) -> Map;
Map; {error, Errors} ->
filter([{Key, Constraints}|Tail], Map) -> exit({validation_failed, Errors})
filter_constraints(Tail, Map, Key, maps:get(Key, Map), Constraints); end.
filter([{Key, Constraints, Default}|Tail], Map) ->
%% Loop through fields, if value is missing and no default,
%% record the error; else if value is missing and has a
%% default, set default; otherwise apply constraints. If
%% constraint fails, record the error.
%%
%% When there is an error at the end, crash.
filter([], Map, Errors) ->
case maps:size(Errors) of
0 -> {ok, Map};
_ -> {error, Errors}
end;
filter([{Key, Constraints}|Tail], Map, Errors) ->
filter_constraints(Tail, Map, Errors, Key, maps:get(Key, Map), Constraints);
filter([{Key, Constraints, Default}|Tail], Map, Errors) ->
case maps:find(Key, Map) of case maps:find(Key, Map) of
{ok, Value} -> {ok, Value} ->
filter_constraints(Tail, Map, Key, Value, Constraints); filter_constraints(Tail, Map, Errors, Key, Value, Constraints);
error -> error ->
filter(Tail, Map#{Key => Default}) filter(Tail, Map#{Key => Default}, Errors)
end; end;
filter([Key|Tail], Map) -> filter([Key|Tail], Map, Errors) ->
true = maps:is_key(Key, Map), case maps:is_key(Key, Map) of
filter(Tail, Map). true ->
filter(Tail, Map, Errors);
false ->
filter(Tail, Map, Errors#{Key => required})
end.
filter_constraints(Tail, Map, Key, Value0, Constraints) -> filter_constraints(Tail, Map, Errors, Key, Value0, Constraints) ->
case cowboy_constraints:validate(Value0, Constraints) of case cowboy_constraints:validate(Value0, Constraints) of
{ok, Value} -> {ok, Value} ->
filter(Tail, Map#{Key => Value}); filter(Tail, Map#{Key => Value}, Errors);
{error, Reason} -> {error, Reason} ->
exit(Reason) filter(Tail, Map, Errors#{Key => Reason})
end. end.