summaryrefslogtreecommitdiff
path: root/src/dreyfus/src/dreyfus_httpd.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/dreyfus/src/dreyfus_httpd.erl')
-rw-r--r--src/dreyfus/src/dreyfus_httpd.erl48
1 files changed, 41 insertions, 7 deletions
diff --git a/src/dreyfus/src/dreyfus_httpd.erl b/src/dreyfus/src/dreyfus_httpd.erl
index 007dace8f..a9259662c 100644
--- a/src/dreyfus/src/dreyfus_httpd.erl
+++ b/src/dreyfus/src/dreyfus_httpd.erl
@@ -532,16 +532,18 @@ hits_to_json(DbName, IncludeDocs, Hits) ->
if IncludeDocs ->
chttpd_stats:incr_reads(length(Hits)),
{ok, JsonDocs} = dreyfus_fabric:get_json_docs(DbName, Ids),
- lists:zipwith(fun(Hit, {Id, Doc}) ->
+ lists:zipwith(fun
+ (Hit, {Id, Doc}) ->
case Hit of
- {Id, Order, Fields} ->
- {[{id, Id}, {order, Order}, {fields, {Fields}}, Doc]};
- {Id, Order, Fields, Highlights} ->
+ {HitId, Order, Fields} ->
+ Doc1 = hits_id_validator(HitId, {Id, Doc}),
+ {[{id, Id}, {order, Order}, {fields, {Fields}}, Doc1]};
+ {HitId, Order, Fields, Highlights} ->
+ Doc1 = hits_id_validator(HitId, {Id, Doc}),
{[{id, Id}, {order, Order}, {fields, {Fields}},
- {highlights, {Highlights}}, Doc]}
+ {highlights, {Highlights}}, Doc1]}
end
- end, HitData, JsonDocs);
-
+ end, HitData, JsonDocs);
true ->
lists:map(fun(Hit) ->
case Hit of
@@ -553,6 +555,21 @@ hits_to_json(DbName, IncludeDocs, Hits) ->
end, HitData)
end.
+
+% _all_docs returned {error, false} meaning document doesn't exist
+hits_id_validator(HitId, {error, false}) ->
+ couch_log:error("HitId: ~p does not exist in db. Index may be out of sync or corrupt", [HitId]),
+ {error, <<"not_found">>};
+hits_id_validator(HitId, {error, Reason}) ->
+ couch_log:error("HitId: ~p does not exist in db. Reason: ~p", [HitId, Reason]),
+ {error, Reason};
+hits_id_validator(HitId, {DocId, Doc}) when DocId =:= HitId ->
+ Doc;
+hits_id_validator(HitId, {DocId, _}) ->
+ couch_log:error("HitId: ~p DocId: ~p mismatch. Index maybe out of sync or corrupt.", [HitId, DocId]),
+ {error, <<"docid mismatch">>}.
+
+
get_hit_data(Hit) ->
Id = couch_util:get_value(<<"_id">>, Hit#hit.fields),
Fields = lists:keydelete(<<"_id">>, 1, Hit#hit.fields),
@@ -612,3 +629,20 @@ backoff_and_retry(Req, Db, DDoc, RetryCount, RetryPause, Error) ->
timer:sleep(RetryPause),
handle_search_req(Req, Db, DDoc, RetryCount + 1, RetryPause * 2)
end.
+
+
+-ifdef(TEST).
+-include_lib("eunit/include/eunit.hrl").
+
+hits_id_validator_test() ->
+ Doc = {doc, {[
+ {<<"_id">>, <<"foo">>},
+ {<<"_rev">>, <<"1-4c6114c65e295552ab1019e2b046b10e">>},
+ {<<"foo">>, <<"bar">>}
+ ]}},
+ ?assertEqual(Doc, hits_id_validator(<<"foo">>, {<<"foo">>, Doc})),
+ ?assertEqual({error, <<"not_found">>}, hits_id_validator(<<"foo>">>, {error, false})),
+ ?assertEqual({error, some_reason}, hits_id_validator(<<"foo>">>, {error, some_reason})),
+ ?assertEqual({error, <<"docid mismatch">>}, hits_id_validator(<<"bar">>, {<<"foo">>, Doc})).
+
+-endif.