couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jch...@apache.org
Subject svn commit: r773387 - in /couchdb/trunk: share/www/script/test/basics.js share/www/script/test/view_errors.js src/couchdb/couch_httpd.erl src/couchdb/couch_httpd_db.erl src/couchdb/couch_httpd_misc_handlers.erl src/couchdb/couch_httpd_view.erl
Date Sun, 10 May 2009 19:20:23 GMT
Author: jchris
Date: Sun May 10 19:20:23 2009
New Revision: 773387

URL: http://svn.apache.org/viewvc?rev=773387&view=rev
Log:
refactor JSON body error handling, also consolidate update_docs JSON response generation.

Modified:
    couchdb/trunk/share/www/script/test/basics.js
    couchdb/trunk/share/www/script/test/view_errors.js
    couchdb/trunk/src/couchdb/couch_httpd.erl
    couchdb/trunk/src/couchdb/couch_httpd_db.erl
    couchdb/trunk/src/couchdb/couch_httpd_misc_handlers.erl
    couchdb/trunk/src/couchdb/couch_httpd_view.erl

Modified: couchdb/trunk/share/www/script/test/basics.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/basics.js?rev=773387&r1=773386&r2=773387&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/basics.js (original)
+++ couchdb/trunk/share/www/script/test/basics.js Sun May 10 19:20:23 2009
@@ -204,14 +204,14 @@
     T(xhr.status == 400);
     result = JSON.parse(xhr.responseText);
     T(result.error == "bad_request");
-    T(result.reason == "Body must be a JSON object");
+    T(result.reason == "Request body must be a JSON object");
 
     // Body of an _all_docs  multi-get is not a {"key": [...]} structure.
     xhr = CouchDB.request("POST", "/test_suite_db/_all_docs", {body: "[]"});
     T(xhr.status == 400);
     result = JSON.parse(xhr.responseText);
     T(result.error == "bad_request");
-    T(result.reason == "Body must be a JSON object");
+    T(result.reason == "Request body must be a JSON object");
     var data = "{\"keys\": 1}";
     xhr = CouchDB.request("POST", "/test_suite_db/_all_docs", {body:data});
     T(xhr.status == 400);

Modified: couchdb/trunk/share/www/script/test/view_errors.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/view_errors.js?rev=773387&r1=773386&r2=773387&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/view_errors.js (original)
+++ couchdb/trunk/share/www/script/test/view_errors.js Sun May 10 19:20:23 2009
@@ -123,7 +123,7 @@
   T(xhr.status == 400);
   result = JSON.parse(xhr.responseText);
   T(result.error == "bad_request");
-  T(result.reason == "Body must be a JSON object");
+  T(result.reason == "Request body must be a JSON object");
   var data = "{\"keys\": 1}";
   xhr = CouchDB.request("POST", path, {body:data});
   T(xhr.status == 400);

Modified: couchdb/trunk/src/couchdb/couch_httpd.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd.erl?rev=773387&r1=773386&r2=773387&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd.erl Sun May 10 19:20:23 2009
@@ -17,7 +17,7 @@
 
 -export([header_value/2,header_value/3,qs_value/2,qs_value/3,qs/1,path/1,absolute_uri/2]).
 -export([verify_is_server_admin/1,unquote/1,quote/1,recv/2,recv_chunked/4,error_info/1]).
--export([parse_form/1,json_body/1,body/1,doc_etag/1, make_etag/1, etag_respond/3]).
+-export([parse_form/1,json_body/1,json_body_obj/1,body/1,doc_etag/1, make_etag/1, etag_respond/3]).
 -export([primary_header_value/2,partition/1,serve_file/3]).
 -export([start_chunked_response/3,send_chunk/2]).
 -export([start_json_response/2, start_json_response/3, end_json_response/1]).
@@ -299,6 +299,14 @@
 json_body(Httpd) ->
     ?JSON_DECODE(body(Httpd)).
 
+json_body_obj(Httpd) ->
+    case json_body(Httpd) of
+        {Props} -> {Props};
+        _Else -> 
+            throw({bad_request, "Request body must be a JSON object"})
+    end.
+
+
 doc_etag(#doc{revs={Start, [DiskRev|_]}}) ->
     "\"" ++ ?b2l(couch_doc:rev_to_str({Start, DiskRev})) ++ "\"".
 

Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=773387&r1=773386&r2=773387&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Sun May 10 19:20:23 2009
@@ -207,13 +207,7 @@
 
 db_req(#httpd{method='POST',path_parts=[_,<<"_bulk_docs">>]}=Req, Db) ->
     couch_stats_collector:increment({httpd, bulk_requests}),
-    JsonProps =
-    case couch_httpd:json_body(Req) of
-    {Fields} ->
-        Fields;
-    _ ->
-        throw({bad_request, "Body must be a JSON object"})
-    end,
+    {JsonProps} = couch_httpd:json_body_obj(Req),
     DocsArray = proplists:get_value(<<"docs">>, JsonProps),
     case couch_httpd:header_value(Req, "X-Couch-Full-Commit", "false") of
     "true" ->
@@ -249,47 +243,26 @@
         case couch_db:update_docs(Db, Docs, Options2) of
         {ok, Results} ->
             % output the results
-            DocResults = lists:zipwith(
-                fun(Doc, {ok, NewRev}) ->
-                    {[{<<"id">>, Doc#doc.id}, {<<"rev">>, couch_doc:rev_to_str(NewRev)}]};
-                (Doc, Error) ->
-                    {_Code, Err, Msg} = couch_httpd:error_info(Error),
-                    % maybe we should add the http error code to the json?
-                    {[{<<"id">>, Doc#doc.id}, {<<"error">>, Err},
{"reason", Msg}]}
-                end,
+            DocResults = lists:zipwith(fun update_doc_result_to_json/2,
                 Docs, Results),
             send_json(Req, 201, DocResults);
         {aborted, Errors} ->
             ErrorsJson = 
-                lists:map(
-                    fun({{Id, Rev}, Error}) ->
-                        {_Code, Err, Msg} = couch_httpd:error_info(Error),
-                        {[{<<"id">>, Id},
-                            {<<"rev">>, couch_doc:rev_to_str(Rev)},
-                            {<<"error">>, Err},
-                            {"reason", Msg}]}
-                    end, Errors),
+                lists:map(fun update_doc_result_to_json/1, Errors),
             send_json(Req, 417, ErrorsJson)
         end;
     false ->
         Docs = [couch_doc:from_json_obj(JsonObj) || JsonObj <- DocsArray],
         {ok, Errors} = couch_db:update_docs(Db, Docs, Options, replicated_changes),
         ErrorsJson = 
-            lists:map(
-                fun({{Id, Rev}, Error}) ->
-                    {_Code, Err, Msg} = couch_httpd:error_info(Error),
-                    {[{<<"id">>, Id},
-                        {<<"rev">>, couch_doc:rev_to_str(Rev)},
-                        {<<"error">>, Err},
-                        {"reason", Msg}]}
-                end, Errors),
+            lists:map(fun update_doc_result_to_json/1, Errors),
         send_json(Req, 201, ErrorsJson)
     end;
 db_req(#httpd{path_parts=[_,<<"_bulk_docs">>]}=Req, _Db) ->
     send_method_not_allowed(Req, "POST");
 
 db_req(#httpd{method='POST',path_parts=[_,<<"_purge">>]}=Req, Db) ->
-    {IdsRevs} = couch_httpd:json_body(Req),
+    {IdsRevs} = couch_httpd:json_body_obj(Req),
     IdsRevs2 = [{Id, couch_doc:parse_revs(Revs)} || {Id, Revs} <- IdsRevs],
     
     case couch_db:purge_docs(Db, IdsRevs2) of
@@ -307,19 +280,15 @@
     all_docs_view(Req, Db, nil);
 
 db_req(#httpd{method='POST',path_parts=[_,<<"_all_docs">>]}=Req, Db) ->
-    case couch_httpd:json_body(Req) of
-    {Fields} ->
-        case proplists:get_value(<<"keys">>, Fields, nil) of
-        nil ->
-            ?LOG_DEBUG("POST to _all_docs with no keys member.", []),
-            all_docs_view(Req, Db, nil);
-        Keys when is_list(Keys) ->
-            all_docs_view(Req, Db, Keys);
-        _ ->
-            throw({bad_request, "`keys` member must be a array."})
-        end;
+    {Fields} = couch_httpd:json_body_obj(Req),
+    case proplists:get_value(<<"keys">>, Fields, nil) of
+    nil ->
+        ?LOG_DEBUG("POST to _all_docs with no keys member.", []),
+        all_docs_view(Req, Db, nil);
+    Keys when is_list(Keys) ->
+        all_docs_view(Req, Db, Keys);
     _ ->
-        throw({bad_request, "Body must be a JSON object"})
+        throw({bad_request, "`keys` member must be a array."})
     end;
 
 db_req(#httpd{path_parts=[_,<<"_all_docs">>]}=Req, _Db) ->
@@ -382,7 +351,7 @@
     send_method_not_allowed(Req, "GET,HEAD");
 
 db_req(#httpd{method='POST',path_parts=[_,<<"_missing_revs">>]}=Req, Db) ->
-    {JsonDocIdRevs} = couch_httpd:json_body(Req),
+    {JsonDocIdRevs} = couch_httpd:json_body_obj(Req),
     JsonDocIdRevs2 = [{Id, [couch_doc:parse_rev(RevStr) || RevStr <- RevStrs]} || {Id,
RevStrs} <- JsonDocIdRevs],
     {ok, Results} = couch_db:get_missing_revs(Db, JsonDocIdRevs2),
     Results2 = [{Id, [couch_doc:rev_to_str(Rev) || Rev <- Revs]} || {Id, Revs} <- Results],
@@ -640,7 +609,7 @@
     case couch_db:update_doc(Db, Doc#doc{id=TargetDocId, revs=TargetRevs}, []) of
     {ok, NewTargetRev} ->
         send_json(Req, 201, [{"Etag", "\"" ++ ?b2l(couch_doc:rev_to_str(NewTargetRev)) ++
"\""}],
-            update_result_to_json({ok, NewTargetRev}));
+            update_doc_result_to_json(TargetDocId, {ok, NewTargetRev}));
     Error ->
         throw(Error)
     end;
@@ -648,11 +617,19 @@
 db_doc_req(Req, _Db, _DocId) ->
     send_method_not_allowed(Req, "DELETE,GET,HEAD,POST,PUT,COPY").
 
-update_result_to_json({ok, NewRev}) ->
-    {[{rev, couch_doc:rev_to_str(NewRev)}]};
-update_result_to_json(Error) ->
+
+update_doc_result_to_json({{Id, Rev}, Error}) ->
+        {_Code, Err, Msg} = couch_httpd:error_info(Error),
+        {[{id, Id}, {rev, couch_doc:rev_to_str(Rev)},
+            {error, Err}, {reason, Msg}]}.
+
+update_doc_result_to_json(#doc{id=DocId}, Result) ->
+    update_doc_result_to_json(DocId, Result);
+update_doc_result_to_json(DocId, {ok, NewRev}) ->
+    {[{id, DocId}, {rev, couch_doc:rev_to_str(NewRev)}]};
+update_doc_result_to_json(DocId, Error) ->
     {_Code, ErrorStr, Reason} = couch_httpd:error_info(Error),
-    {[{error, ErrorStr}, {reason, Reason}]}.
+    {[{id, DocId}, {error, ErrorStr}, {reason, Reason}]}.
 
 
 update_doc(Req, Db, DocId, Json) ->

Modified: couchdb/trunk/src/couchdb/couch_httpd_misc_handlers.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_misc_handlers.erl?rev=773387&r1=773386&r2=773387&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_misc_handlers.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_misc_handlers.erl Sun May 10 19:20:23 2009
@@ -91,7 +91,7 @@
     {local, DbName, UserCtx}.
 
 handle_replicate_req(#httpd{method='POST'}=Req) ->
-    {Props} = couch_httpd:json_body(Req),
+    {Props} = couch_httpd:json_body_obj(Req),
     Source = get_rep_endpoint(Req, proplists:get_value(<<"source">>, Props)),
     Target = get_rep_endpoint(Req, proplists:get_value(<<"target">>, Props)),
     case couch_rep:replicate(Source, Target) of

Modified: couchdb/trunk/src/couchdb/couch_httpd_view.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_view.erl?rev=773387&r1=773386&r2=773387&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_view.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_view.erl Sun May 10 19:20:23 2009
@@ -58,20 +58,16 @@
 
 handle_view_req(#httpd{method='POST',
         path_parts=[_Db, _Design, DName, _View, ViewName]}=Req, Db) ->
-    case couch_httpd:json_body(Req) of
-    {Fields} ->
-        case proplists:get_value(<<"keys">>, Fields, nil) of
-        nil ->
-            Fmt = "POST to view ~p/~p in database ~p with no keys member.",
-            ?LOG_DEBUG(Fmt, [DName, ViewName, Db]),
-            design_doc_view(Req, Db, DName, ViewName, nil);
-        Keys when is_list(Keys) ->
-            design_doc_view(Req, Db, DName, ViewName, Keys);
-        _ ->
-            throw({bad_request, "`keys` member must be a array."})
-        end;
+    {Fields} = couch_httpd:json_body_obj(Req),
+    case proplists:get_value(<<"keys">>, Fields, nil) of
+    nil ->
+        Fmt = "POST to view ~p/~p in database ~p with no keys member.",
+        ?LOG_DEBUG(Fmt, [DName, ViewName, Db]),
+        design_doc_view(Req, Db, DName, ViewName, nil);
+    Keys when is_list(Keys) ->
+        design_doc_view(Req, Db, DName, ViewName, Keys);
     _ ->
-        throw({bad_request, "Body must be a JSON object"})
+        throw({bad_request, "`keys` member must be a array."})
     end;
 
 handle_view_req(Req, _Db) ->
@@ -79,7 +75,7 @@
 
 handle_temp_view_req(#httpd{method='POST'}=Req, Db) ->
     couch_stats_collector:increment({httpd, temporary_view_reads}),
-    {Props} = couch_httpd:json_body(Req),
+    {Props} = couch_httpd:json_body_obj(Req),
     Language = proplists:get_value(<<"language">>, Props, <<"javascript">>),
     {DesignOptions} = proplists:get_value(<<"options">>, Props, {[]}),
     MapSrc = proplists:get_value(<<"map">>, Props),



Mime
View raw message