You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by fd...@apache.org on 2010/09/13 13:00:50 UTC

svn commit: r996493 - in /couchdb/branches/1.0.x/src/couchdb: couch_httpd_misc_handlers.erl couch_rep.erl couch_rep_reader.erl couch_util.erl

Author: fdmanana
Date: Mon Sep 13 11:00:49 2010
New Revision: 996493

URL: http://svn.apache.org/viewvc?rev=996493&view=rev
Log:
Merged revision 996492 from trunk:

Replicator changes:

1) avoid badmatch exceptions when there's a failure opening a single document from a remote source;
2) add error log messages describing which remote documents couldn't be opened and why;
3) when replications errors can't be encoded as json, convert and send them as json strings  

Closes COUCHDB-884.

Modified:
    couchdb/branches/1.0.x/src/couchdb/couch_httpd_misc_handlers.erl
    couchdb/branches/1.0.x/src/couchdb/couch_rep.erl
    couchdb/branches/1.0.x/src/couchdb/couch_rep_reader.erl
    couchdb/branches/1.0.x/src/couchdb/couch_util.erl

Modified: couchdb/branches/1.0.x/src/couchdb/couch_httpd_misc_handlers.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_httpd_misc_handlers.erl?rev=996493&r1=996492&r2=996493&view=diff
==============================================================================
--- couchdb/branches/1.0.x/src/couchdb/couch_httpd_misc_handlers.erl (original)
+++ couchdb/branches/1.0.x/src/couchdb/couch_httpd_misc_handlers.erl Mon Sep 13 11:00:49 2010
@@ -93,7 +93,12 @@ handle_replicate_req(#httpd{method='POST
     {error, not_found} ->
         send_json(Req, 404, {[{error, not_found}]});
     {error, Reason} ->
-        send_json(Req, 500, {[{error, Reason}]})
+        try
+            send_json(Req, 500, {[{error, Reason}]})
+        catch
+        exit:{json_encode, _} ->
+            send_json(Req, 500, {[{error, couch_util:to_binary(Reason)}]})
+        end
     catch
     throw:{db_not_found, Msg} ->
         send_json(Req, 404, {[{error, db_not_found}, {reason, Msg}]})

Modified: couchdb/branches/1.0.x/src/couchdb/couch_rep.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_rep.erl?rev=996493&r1=996492&r2=996493&view=diff
==============================================================================
--- couchdb/branches/1.0.x/src/couchdb/couch_rep.erl (original)
+++ couchdb/branches/1.0.x/src/couchdb/couch_rep.erl Mon Sep 13 11:00:49 2010
@@ -354,16 +354,10 @@ close_db(Db) ->
     couch_db:close(Db).
 
 dbname(#http_db{url = Url}) ->
-    strip_password(Url);
+    couch_util:url_strip_password(Url);
 dbname(#db{name = Name}) ->
     Name.
 
-strip_password(Url) ->
-    re:replace(Url,
-        "http(s)?://([^:]+):[^@]+@(.*)$",
-        "http\\1://\\2:*****@\\3",
-        [{return, list}]).
-
 dbinfo(#http_db{} = Db) ->
     {DbProps} = couch_rep_httpc:request(Db),
     [{list_to_existing_atom(?b2l(K)), V} || {K,V} <- DbProps];

Modified: couchdb/branches/1.0.x/src/couchdb/couch_rep_reader.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_rep_reader.erl?rev=996493&r1=996492&r2=996493&view=diff
==============================================================================
--- couchdb/branches/1.0.x/src/couchdb/couch_rep_reader.erl (original)
+++ couchdb/branches/1.0.x/src/couchdb/couch_rep_reader.erl Mon Sep 13 11:00:49 2010
@@ -230,7 +230,7 @@ update_sequence_lists(Seq, State) ->
         opened_seqs = Opened
     }.
 
-open_doc_revs(#http_db{} = DbS, DocId, Revs) ->
+open_doc_revs(#http_db{url = Url} = DbS, DocId, Revs) ->
     %% all this logic just splits up revision lists that are too long for
     %% MochiWeb into multiple requests
     BaseQS = [{revs,true}, {latest,true}, {att_encoding_info,true}],
@@ -246,28 +246,39 @@ open_doc_revs(#http_db{} = DbS, DocId, R
     JsonResults = lists:flatten([couch_rep_httpc:request(R) || R <- Requests]),
 
     Transform =
-    fun({[{<<"missing">>, Rev}]}) ->
-        {{not_found, missing}, couch_doc:parse_rev(Rev)};
-    ({[{<<"ok">>, Json}]}) ->
+    fun({[{<<"ok">>, Json}]}, Acc) ->
         #doc{id=Id, revs=Rev, atts=Atts} = Doc = couch_doc:from_json_obj(Json),
-        Doc#doc{atts=[couch_rep_att:convert_stub(A, {DbS,Id,Rev}) || A <- Atts]}
+        Doc1 = Doc#doc{
+            atts=[couch_rep_att:convert_stub(A, {DbS,Id,Rev}) || A <- Atts]
+        },
+        [Doc1 | Acc];
+    ({ErrorProps}, Acc) ->
+        Err = couch_util:get_value(<<"error">>, ErrorProps,
+            ?JSON_ENCODE({ErrorProps})),
+        ?LOG_ERROR("Replicator: error accessing doc ~s at ~s, reason: ~s",
+           [DocId, couch_util:url_strip_password(Url), Err]),
+        Acc
     end,
-    [Transform(Result) || Result <- JsonResults].
+    lists:reverse(lists:foldl(Transform, [], JsonResults)).
 
-open_doc(#http_db{} = DbS, DocId) ->
+open_doc(#http_db{url = Url} = DbS, DocId) ->
     % get latest rev of the doc
     Req = DbS#http_db{
         resource=url_encode(DocId),
         qs=[{att_encoding_info, true}]
     },
-    case couch_rep_httpc:request(Req) of
-    {[{<<"error">>,<<"not_found">>}, {<<"reason">>,<<"missing">>}]} ->
-        [];
-    Json ->
+    {Props} = Json = couch_rep_httpc:request(Req),
+    case couch_util:get_value(<<"_id">>, Props) of
+    Id when is_binary(Id) ->
         #doc{id=Id, revs=Rev, atts=Atts} = Doc = couch_doc:from_json_obj(Json),
         [Doc#doc{
             atts=[couch_rep_att:convert_stub(A, {DbS,Id,Rev}) || A <- Atts]
-        }]
+        }];
+    undefined ->
+        Err = couch_util:get_value(<<"error">>, Props, ?JSON_ENCODE(Json)),
+        ?LOG_ERROR("Replicator: error accessing doc ~s at ~s, reason: ~s",
+            [DocId, couch_util:url_strip_password(Url), Err]),
+        []
     end.
 
 reader_loop(ReaderServer, Source, DocIds) when is_list(DocIds) ->

Modified: couchdb/branches/1.0.x/src/couchdb/couch_util.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_util.erl?rev=996493&r1=996492&r2=996493&view=diff
==============================================================================
--- couchdb/branches/1.0.x/src/couchdb/couch_util.erl (original)
+++ couchdb/branches/1.0.x/src/couchdb/couch_util.erl Mon Sep 13 11:00:49 2010
@@ -27,6 +27,7 @@
 -export([get_value/2, get_value/3]).
 -export([md5/1, md5_init/0, md5_update/2, md5_final/1]).
 -export([reorder_results/2]).
+-export([url_strip_password/1]).
 
 -include("couch_db.hrl").
 -include_lib("kernel/include/file.hrl").
@@ -452,3 +453,9 @@ reorder_results(Keys, SortedResults) whe
 reorder_results(Keys, SortedResults) ->
     KeyDict = dict:from_list(SortedResults),
     [dict:fetch(Key, KeyDict) || Key <- Keys].
+
+url_strip_password(Url) ->
+    re:replace(Url,
+        "http(s)?://([^:]+):[^@]+@(.*)$",
+        "http\\1://\\2:*****@\\3",
+        [{return, list}]).