This is an automated email from the ASF dual-hosted git repository. vatamane pushed a commit to branch handle-bad-request-triple in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 7e3255d14d6acdfc56b76d45bb4db63e4491a33f Author: Nick Vatamaniuc <[email protected]> AuthorDate: Thu Mar 26 18:16:08 2026 -0400 Handle a bad_request triple in fabric_doc_update Besides the `{bad_request, Msg}` also handle the `{bad_request, Error, Reason}` triple. Design document validator can return those [1], for instance. While at it add a test to cover both the tuple and the triple case. [1] https://github.com/apache/couchdb/blob/997deea76f4489e2e8702bb7dbf50eceffdd5650/src/couch/src/couch_db.erl#L984-L986 --- src/fabric/src/fabric_doc_update.erl | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/fabric/src/fabric_doc_update.erl b/src/fabric/src/fabric_doc_update.erl index 7f3e2095c..89fb9618d 100644 --- a/src/fabric/src/fabric_doc_update.erl +++ b/src/fabric/src/fabric_doc_update.erl @@ -148,6 +148,8 @@ handle_message({not_found, no_db_file} = X, Worker, #acc{} = Acc0) -> handle_message({ok, [X || _D <- Docs]}, Worker, Acc0); handle_message({bad_request, Msg}, _, _) -> throw({bad_request, Msg}); +handle_message({bad_request, Error, Reason}, _, _) -> + throw({bad_request, Error, Reason}); handle_message({forbidden, Msg}, _, _) -> throw({forbidden, Msg}); handle_message({request_entity_too_large, Entity}, _, _) -> @@ -484,7 +486,8 @@ doc_update_test_() -> fun other_errors_one_forbid/0, fun one_error_two_forbid/0, fun one_success_two_forbid/0, - fun worker_before_doc_update_forbidden/0 + fun worker_before_doc_update_forbidden/0, + fun handle_bad_request/0 ] }. @@ -965,6 +968,28 @@ worker_before_doc_update_forbidden() -> }, ?assertThrow({forbidden, <<"msg">>}, handle_message({forbidden, <<"msg">>}, hd(Shards), Acc)). +handle_bad_request() -> + Doc1 = #doc{revs = {1, [<<"foo">>]}}, + Docs = [Doc1], + Shards = + mem3_util:create_partition_map("foo", 3, 1, ["node1", "node2", "node3"]), + GroupedDocs = group_docs_by_shard_hack(<<"foo">>, Shards, Docs), + Acc = #acc{ + waiting_count = length(Shards), + doc_count = length(Docs), + w = 2, + grouped_docs = GroupedDocs, + reply = dict:from_list([{Doc, []} || Doc <- Docs]) + }, + ?assertThrow( + {bad_request, msg}, + handle_message({bad_request, msg}, hd(Shards), Acc) + ), + ?assertThrow( + {bad_request, err, reason}, + handle_message({bad_request, err, reason}, hd(Shards), Acc) + ). + % needed for testing to avoid having to start the mem3 application group_docs_by_shard_hack(_DbName, Shards, Docs) -> dict:to_list(
