You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2011/04/17 15:27:18 UTC

svn commit: r1094143 - in /couchdb/trunk: THANKS share/www/script/test/bulk_docs.js src/couchdb/couch_httpd_db.erl

Author: jan
Date: Sun Apr 17 13:27:18 2011
New Revision: 1094143

URL: http://svn.apache.org/viewvc?rev=1094143&view=rev
Log:
Return proper error message when 'docs' member is missing in _bulk_docs
request bodies.

Closes COUCHDB-910

Patch by Dipesh Patel.

Modified:
    couchdb/trunk/THANKS
    couchdb/trunk/share/www/script/test/bulk_docs.js
    couchdb/trunk/src/couchdb/couch_httpd_db.erl

Modified: couchdb/trunk/THANKS
URL: http://svn.apache.org/viewvc/couchdb/trunk/THANKS?rev=1094143&r1=1094142&r2=1094143&view=diff
==============================================================================
--- couchdb/trunk/THANKS (original)
+++ couchdb/trunk/THANKS Sun Apr 17 13:27:18 2011
@@ -79,5 +79,6 @@ suggesting improvements or submitting ch
  * Thomas Vander Stichele <th...@apestaart.org>
  * Felix Hummel <ap...@felixhummel.de>
  * Tim Smith <ti...@couchbase.com>
+ * Dipesh Patel <di...@googlemail.com>
 
 For a list of authors see the `AUTHORS` file.

Modified: couchdb/trunk/share/www/script/test/bulk_docs.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/bulk_docs.js?rev=1094143&r1=1094142&r2=1094143&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/bulk_docs.js (original)
+++ couchdb/trunk/share/www/script/test/bulk_docs.js Sun Apr 17 13:27:18 2011
@@ -97,4 +97,15 @@ couchTests.bulk_docs = function(debug) {
   var torem = {"_id": newdoc._id, "_rev": newdoc._rev, "_deleted": true};
   results = db.bulkSave([update, torem]);
   T(results[0].error == "conflict" || results[1].error == "conflict");
+
+
+  // verify that sending a request with no docs causes error thrown
+  var req = CouchDB.request("POST", "/test_suite_db/_bulk_docs", {
+    body: JSON.stringify({"doc": [{"foo":"bar"}]})
+  });
+
+  T(req.status == 400 );
+  result = JSON.parse(req.responseText);
+  T(result.error == "bad_request");
+  T(result.reason == "Missing JSON list of 'docs'");
 };

Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=1094143&r1=1094142&r2=1094143&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Sun Apr 17 13:27:18 2011
@@ -23,7 +23,7 @@
     send_response/4,start_json_response/2,start_json_response/3,
     send_chunk/2,last_chunk/1,end_json_response/1,
     start_chunked_response/3, absolute_uri/2, send/2,
-    start_response_length/4]).
+    start_response_length/4, send_error/4]).
 
 -record(doc_query_args, {
     options = [],
@@ -283,61 +283,65 @@ db_req(#httpd{method='POST',path_parts=[
     couch_stats_collector:increment({httpd, bulk_requests}),
     couch_httpd:validate_ctype(Req, "application/json"),
     {JsonProps} = couch_httpd:json_body_obj(Req),
-    DocsArray = couch_util:get_value(<<"docs">>, JsonProps),
-    case couch_httpd:header_value(Req, "X-Couch-Full-Commit") of
-    "true" ->
-        Options = [full_commit];
-    "false" ->
-        Options = [delay_commit];
-    _ ->
-        Options = []
-    end,
-    case couch_util:get_value(<<"new_edits">>, JsonProps, true) of
-    true ->
-        Docs = lists:map(
-            fun({ObjProps} = JsonObj) ->
-                Doc = couch_doc:from_json_obj(JsonObj),
-                validate_attachment_names(Doc),
-                Id = case Doc#doc.id of
-                    <<>> -> couch_uuids:new();
-                    Id0 -> Id0
-                end,
-                case couch_util:get_value(<<"_rev">>, ObjProps) of
-                undefined ->
-                    Revs = {0, []};
-                Rev  ->
-                    {Pos, RevId} = couch_doc:parse_rev(Rev),
-                    Revs = {Pos, [RevId]}
+    case couch_util:get_value(<<"docs">>, JsonProps) of
+    undefined ->
+        send_error(Req, 400, <<"bad_request">>, <<"Missing JSON list of 'docs'">>);
+    DocsArray ->
+        case couch_httpd:header_value(Req, "X-Couch-Full-Commit") of
+        "true" ->
+            Options = [full_commit];
+        "false" ->
+            Options = [delay_commit];
+        _ ->
+            Options = []
+        end,
+        case couch_util:get_value(<<"new_edits">>, JsonProps, true) of
+        true ->
+            Docs = lists:map(
+                fun({ObjProps} = JsonObj) ->
+                    Doc = couch_doc:from_json_obj(JsonObj),
+                    validate_attachment_names(Doc),
+                    Id = case Doc#doc.id of
+                        <<>> -> couch_uuids:new();
+                        Id0 -> Id0
+                    end,
+                    case couch_util:get_value(<<"_rev">>, ObjProps) of
+                    undefined ->
+                       Revs = {0, []};
+                    Rev  ->
+                        {Pos, RevId} = couch_doc:parse_rev(Rev),
+                        Revs = {Pos, [RevId]}
+                    end,
+                    Doc#doc{id=Id,revs=Revs}
                 end,
-                Doc#doc{id=Id,revs=Revs}
+                DocsArray),
+            Options2 =
+            case couch_util:get_value(<<"all_or_nothing">>, JsonProps) of
+            true  -> [all_or_nothing|Options];
+            _ -> Options
             end,
-            DocsArray),
-        Options2 =
-        case couch_util:get_value(<<"all_or_nothing">>, JsonProps) of
-        true  -> [all_or_nothing|Options];
-        _ -> Options
-        end,
-        case couch_db:update_docs(Db, Docs, Options2) of
-        {ok, Results} ->
-            % output the results
-            DocResults = lists:zipwith(fun update_doc_result_to_json/2,
-                Docs, Results),
-            send_json(Req, 201, DocResults);
-        {aborted, Errors} ->
+            case couch_db:update_docs(Db, Docs, Options2) of
+            {ok, Results} ->
+                % output the results
+                DocResults = lists:zipwith(fun update_doc_result_to_json/2,
+                    Docs, Results),
+                send_json(Req, 201, DocResults);
+            {aborted, Errors} ->
+                ErrorsJson =
+                    lists:map(fun update_doc_result_to_json/1, Errors),
+                send_json(Req, 417, ErrorsJson)
+            end;
+        false ->
+            Docs = lists:map(fun(JsonObj) ->
+                    Doc = couch_doc:from_json_obj(JsonObj),
+                    validate_attachment_names(Doc),
+                    Doc
+                end, DocsArray),
+            {ok, Errors} = couch_db:update_docs(Db, Docs, Options, replicated_changes),
             ErrorsJson =
                 lists:map(fun update_doc_result_to_json/1, Errors),
-            send_json(Req, 417, ErrorsJson)
-        end;
-    false ->
-        Docs = lists:map(fun(JsonObj) ->
-                Doc = couch_doc:from_json_obj(JsonObj),
-                validate_attachment_names(Doc),
-                Doc
-            end, DocsArray),
-        {ok, Errors} = couch_db:update_docs(Db, Docs, Options, replicated_changes),
-        ErrorsJson =
-            lists:map(fun update_doc_result_to_json/1, Errors),
-        send_json(Req, 201, ErrorsJson)
+            send_json(Req, 201, ErrorsJson)
+        end
     end;
 db_req(#httpd{path_parts=[_,<<"_bulk_docs">>]}=Req, _Db) ->
     send_method_not_allowed(Req, "POST");