diff options
author | iilyak <iilyak@ca.ibm.com> | 2018-08-15 12:23:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-15 12:23:58 -0700 |
commit | d3453d22b5daad07e056eb51a994302f7a96e877 (patch) | |
tree | 4ba486787033c31e8147b568745a8dec2871f6ae | |
parent | ed1db09225c3c4757d8d869a4885e89ae3620983 (diff) | |
parent | 39dede765c4cf5ab3006224b04450c9a2ced8f00 (diff) | |
download | couchdb-d3453d22b5daad07e056eb51a994302f7a96e877.tar.gz |
Merge pull request #1486 from cloudant/fix-doc-update-case-clause
Expose document update errors to client
-rw-r--r-- | src/fabric/src/fabric.erl | 58 | ||||
-rw-r--r-- | src/fabric/src/fabric_doc_update.erl | 3 |
2 files changed, 59 insertions, 2 deletions
diff --git a/src/fabric/src/fabric.erl b/src/fabric/src/fabric.erl index f5c793736..5ad9b459d 100644 --- a/src/fabric/src/fabric.erl +++ b/src/fabric/src/fabric.erl @@ -248,7 +248,9 @@ update_doc(DbName, Doc, Options) -> {ok, []} -> % replication success #doc{revs = {Pos, [RevId | _]}} = doc(Doc), - {ok, {Pos, RevId}} + {ok, {Pos, RevId}}; + {error, [Error]} -> + throw(Error) end. %% @doc update a list of docs @@ -261,6 +263,8 @@ update_docs(DbName, Docs, Options) -> {ok, Results}; {accepted, Results} -> {accepted, Results}; + {error, Error} -> + {error, Error}; Error -> throw(Error) catch {aborted, PreCommitFailures} -> @@ -595,3 +599,55 @@ kl_to_record(KeyList,RecName) -> set_namespace(NS, #mrargs{extra = Extra} = Args) -> Args#mrargs{extra = [{namespace, NS} | Extra]}. + + +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). + +update_doc_test_() -> + { + "Update doc tests", { + setup, fun setup/0, fun teardown/1, + fun(Ctx) -> [ + should_throw_conflict(Ctx) + ] end + } + }. + +should_throw_conflict(Doc) -> + ?_test(begin + ?assertThrow(conflict, update_doc(<<"test-db">>, Doc, [])) + end). + + +setup() -> + Doc = #doc{ + id = <<"test_doc">>, + revs = {3, [<<5,68,252,180,43,161,216,223,26,119,71,219,212,229, + 159,113>>]}, + body = {[{<<"foo">>,<<"asdf">>},{<<"author">>,<<"tom">>}]}, + atts = [], deleted = false, meta = [] + }, + ok = application:ensure_started(config), + ok = meck:expect(mem3, shards, fun(_, _) -> [] end), + ok = meck:expect(mem3, quorum, fun(_) -> 1 end), + ok = meck:expect(rexi, cast, fun(_, _) -> ok end), + ok = meck:expect(rexi_utils, recv, + fun(_, _, _, _, _, _) -> + {ok, {error, [{Doc, conflict}]}} + end), + ok = meck:expect(couch_util, reorder_results, + fun(_, [{_, Res}]) -> + [Res] + end), + ok = meck:expect(fabric_util, create_monitors, fun(_) -> ok end), + ok = meck:expect(rexi_monitor, stop, fun(_) -> ok end), + Doc. + + +teardown(_) -> + meck:unload(), + ok = application:stop(config). + + +-endif. diff --git a/src/fabric/src/fabric_doc_update.erl b/src/fabric/src/fabric_doc_update.erl index 214566d91..a4867f31d 100644 --- a/src/fabric/src/fabric_doc_update.erl +++ b/src/fabric/src/fabric_doc_update.erl @@ -37,7 +37,8 @@ go(DbName, AllDocs0, Opts) -> dict:new()}, Timeout = fabric_util:request_timeout(), try rexi_utils:recv(Workers, #shard.ref, fun handle_message/3, Acc0, infinity, Timeout) of - {ok, {Health, Results}} when Health =:= ok; Health =:= accepted -> + {ok, {Health, Results}} + when Health =:= ok; Health =:= accepted; Health =:= error -> {Health, [R || R <- couch_util:reorder_results(AllDocs, Results), R =/= noreply]}; {timeout, Acc} -> {_, _, W1, GroupedDocs1, DocReplDict} = Acc, |