summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriilyak <iilyak@ca.ibm.com>2018-08-15 12:23:58 -0700
committerGitHub <noreply@github.com>2018-08-15 12:23:58 -0700
commitd3453d22b5daad07e056eb51a994302f7a96e877 (patch)
tree4ba486787033c31e8147b568745a8dec2871f6ae
parented1db09225c3c4757d8d869a4885e89ae3620983 (diff)
parent39dede765c4cf5ab3006224b04450c9a2ced8f00 (diff)
downloadcouchdb-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.erl58
-rw-r--r--src/fabric/src/fabric_doc_update.erl3
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,