aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cowboy_req.erl50
1 files changed, 34 insertions, 16 deletions
diff --git a/src/cowboy_req.erl b/src/cowboy_req.erl
index 3eca379..fc82308 100644
--- a/src/cowboy_req.erl
+++ b/src/cowboy_req.erl
@@ -762,28 +762,46 @@ kvlist_to_map(Keys, [{Key, Value}|Tail], Map) ->
kvlist_to_map(Keys, Tail, Map)
end.
-%% Loop through fields, if value is missing and no default, crash;
-%% else if value is missing and has a default, set default;
-%% otherwise apply constraints. If constraint fails, crash.
-filter([], Map) ->
- Map;
-filter([{Key, Constraints}|Tail], Map) ->
- filter_constraints(Tail, Map, Key, maps:get(Key, Map), Constraints);
-filter([{Key, Constraints, Default}|Tail], Map) ->
+filter(Fields, Map0) ->
+ case filter(Fields, Map0, #{}) of
+ {ok, Map} ->
+ Map;
+ {error, Errors} ->
+ exit({validation_failed, Errors})
+ end.
+
+%% 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
{ok, Value} ->
- filter_constraints(Tail, Map, Key, Value, Constraints);
+ filter_constraints(Tail, Map, Errors, Key, Value, Constraints);
error ->
- filter(Tail, Map#{Key => Default})
+ filter(Tail, Map#{Key => Default}, Errors)
end;
-filter([Key|Tail], Map) ->
- true = maps:is_key(Key, Map),
- filter(Tail, Map).
+filter([Key|Tail], Map, Errors) ->
+ case maps:is_key(Key, Map) of
+ 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
{ok, Value} ->
- filter(Tail, Map#{Key => Value});
+ filter(Tail, Map#{Key => Value}, Errors);
{error, Reason} ->
- exit(Reason)
+ filter(Tail, Map, Errors#{Key => Reason})
end.