summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@gmail.com>2022-05-06 15:59:16 -0400
committerNick Vatamaniuc <nickva@users.noreply.github.com>2022-05-06 16:50:45 -0400
commit3cd41c5dfab76ffa2dece825d819918aa9aab35e (patch)
tree82a3504e0846b225eea5e0518862905e9553d8e9
parent3bdbcf53715ed7ef98899891147affca2f3b33dc (diff)
downloadcouchdb-3cd41c5dfab76ffa2dece825d819918aa9aab35e.tar.gz
Fix function_clause error for replicated changes with a target VDU
Previously when handling mismatched responses for replicated changes, where some response were `noreply` and some were `forbidden`, the `{DocID, Rev}` tuple was dropped from the response, which resulted in `update_doc_result_to_json` failing as it expects an `{{DocId, Rev}, Error}` argument instead of just `Error`. Make sure to keep and return the reply as is in`check_forbidden_msg/1`.
-rw-r--r--src/fabric/src/fabric_doc_update.erl28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/fabric/src/fabric_doc_update.erl b/src/fabric/src/fabric_doc_update.erl
index 4cf1ccfc3..b6a588039 100644
--- a/src/fabric/src/fabric_doc_update.erl
+++ b/src/fabric/src/fabric_doc_update.erl
@@ -146,8 +146,8 @@ force_reply(Doc, [FirstReply | _] = Replies, {Health, W, Acc}) ->
{true, Reply} ->
% corner case new_edits:false and vdu: [noreply, forbidden, noreply]
case check_forbidden_msg(Replies) of
- {forbidden, Msg} ->
- {Health, W, [{Doc, {forbidden, Msg}} | Acc]};
+ {forbidden, ForbiddenReply} ->
+ {Health, W, [{Doc, ForbiddenReply} | Acc]};
false ->
{Health, W, [{Doc, Reply} | Acc]}
end;
@@ -164,8 +164,8 @@ force_reply(Doc, [FirstReply | _] = Replies, {Health, W, Acc}) ->
CounterKey = [fabric, doc_update, mismatched_errors],
couch_stats:increment_counter(CounterKey),
case check_forbidden_msg(Replies) of
- {forbidden, Msg} ->
- {Health, W, [{Doc, {forbidden, Msg}} | Acc]};
+ {forbidden, ForbiddenReply} ->
+ {Health, W, [{Doc, ForbiddenReply} | Acc]};
false ->
{error, W, [{Doc, FirstReply} | Acc]}
end
@@ -228,10 +228,10 @@ check_forbidden_msg(Replies) ->
case lists:partition(Pred, Replies) of
{[], _} ->
false;
- {[{_, {forbidden, Msg}} | _], RemReplies} ->
+ {[ForbiddenReply = {_, {forbidden, _}} | _], RemReplies} ->
case lists:all(fun(E) -> E =:= noreply end, RemReplies) of
true ->
- {forbidden, Msg};
+ {forbidden, ForbiddenReply};
false ->
false
end
@@ -497,7 +497,13 @@ one_forbid() ->
{stop, Reply} =
handle_message({ok, [{ok, Doc1}, noreply]}, lists:nth(3, Shards), Acc2),
- ?assertEqual({ok, [{Doc1, {ok, Doc1}}, {Doc2, {forbidden, <<"not allowed">>}}]}, Reply).
+ ?assertEqual(
+ {ok, [
+ {Doc1, {ok, Doc1}},
+ {Doc2, {Doc2, {forbidden, <<"not allowed">>}}}
+ ]},
+ Reply
+ ).
two_forbid() ->
Doc1 = #doc{revs = {1, [<<"foo">>]}},
@@ -530,7 +536,13 @@ two_forbid() ->
{ok, [{ok, Doc1}, {Doc2, {forbidden, <<"not allowed">>}}]}, lists:nth(3, Shards), Acc2
),
- ?assertEqual({ok, [{Doc1, {ok, Doc1}}, {Doc2, {forbidden, <<"not allowed">>}}]}, Reply).
+ ?assertEqual(
+ {ok, [
+ {Doc1, {ok, Doc1}},
+ {Doc2, {Doc2, {forbidden, <<"not allowed">>}}}
+ ]},
+ Reply
+ ).
% This should actually never happen, because an `{ok, Doc}` message means that the revision
% tree is extended and so the VDU should forbid the document.