summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lehnardt <jan@apache.org>2010-02-04 23:09:06 +0000
committerJan Lehnardt <jan@apache.org>2010-02-04 23:09:06 +0000
commitff1618779bc85d8f16d6aeebec461fad51b008c5 (patch)
tree253733cda59e10beb486b4903d43f21f795d227c
parenta75bc7b281952eed8dda9e0c09e3fe386bbe9f32 (diff)
re-enable 404 handling in show functions while retaining user-friendly error behaviour
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@906721 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--share/server/render.js6
-rw-r--r--share/www/script/test/show_documents.js20
-rw-r--r--src/couchdb/couch_httpd_show.erl32
3 files changed, 43 insertions, 15 deletions
diff --git a/share/server/render.js b/share/server/render.js
index 45782d76..11c76373 100644
--- a/share/server/render.js
+++ b/share/server/render.js
@@ -227,7 +227,11 @@ var Render = (function() {
throw(["error", "render_error", "undefined response from show function"]);
}
} catch(e) {
- renderError(e, fun.toSource());
+ if(args[0] === null) {
+ throw(["error", "not_found", "document not found"]);
+ } else {
+ renderError(e, fun.toSource());
+ }
}
};
diff --git a/share/www/script/test/show_documents.js b/share/www/script/test/show_documents.js
index bdb1b73e..2e895838 100644
--- a/share/www/script/test/show_documents.js
+++ b/share/www/script/test/show_documents.js
@@ -22,10 +22,15 @@ couchTests.show_documents = function(debug) {
shows: {
"hello" : stringFun(function(doc, req) {
log("hello fun");
+ log(req);
if (doc) {
return "Hello World";
} else {
- return "Empty World";
+ if(req.id) {
+ return "New World";
+ } else {
+ return "Empty World";
+ }
}
}),
"just-name" : stringFun(function(doc, req) {
@@ -56,6 +61,9 @@ couchTests.show_documents = function(debug) {
"empty" : stringFun(function(doc, req) {
return "";
}),
+ "fail" : stringFun(function(doc, req) {
+ return doc._id;
+ }),
"xml-type" : stringFun(function(doc, req) {
return {
"headers" : {
@@ -161,7 +169,7 @@ couchTests.show_documents = function(debug) {
T(xhr.responseText == "");
// // hello template world (non-existing docid)
- xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/hello/nonExistingDoc");
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/fail/nonExistingDoc");
T(xhr.status == 404);
var resp = JSON.parse(xhr.responseText);
T(resp.error == "not_found");
@@ -173,8 +181,7 @@ couchTests.show_documents = function(debug) {
// show with missing doc
xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/just-name/missingdoc");
T(xhr.status == 404);
- var resp = JSON.parse(xhr.responseText);
- T(resp.error == "not_found");
+ TEquals("No such doc", xhr.responseText);
// show with missing func
xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/missing/"+docid);
@@ -350,5 +357,10 @@ couchTests.show_documents = function(debug) {
db.save(doc3);
xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/withSlash/a/b/c");
T(xhr.status == 200);
+
+ // hello template world (non-existing docid)
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/hello/nonExistingDoc");
+ T(xhr.responseText == "New World");
+
};
diff --git a/src/couchdb/couch_httpd_show.erl b/src/couchdb/couch_httpd_show.erl
index 3e660be1..18f24e85 100644
--- a/src/couchdb/couch_httpd_show.erl
+++ b/src/couchdb/couch_httpd_show.erl
@@ -13,7 +13,7 @@
-module(couch_httpd_show).
-export([handle_doc_show_req/3, handle_doc_update_req/3, handle_view_list_req/3,
- handle_doc_show/5, handle_view_list/6, get_fun_key/3]).
+ handle_view_list/6, get_fun_key/3]).
-include("couch_db.hrl").
@@ -23,31 +23,40 @@
start_chunked_response/3, send_error/4]).
-% /db/_design/foo/show/bar/docid
+% /db/_design/foo/_show/bar/docid
% show converts a json doc to a response of any content-type.
% it looks up the doc an then passes it to the query server.
% then it sends the response from the query server to the http client.
+
+maybe_open_doc(Db, DocId) ->
+ case catch couch_httpd_db:couch_doc_open(Db, DocId, nil, [conflicts]) of
+ {not_found, missing} -> nil;
+ Doc -> Doc
+ end.
handle_doc_show_req(#httpd{
path_parts=[_, _, _, _, ShowName, DocId]
}=Req, Db, DDoc) ->
+
% open the doc
- Doc = couch_httpd_db:couch_doc_open(Db, DocId, nil, [conflicts]),
+ Doc = maybe_open_doc(Db, DocId),
+
% we don't handle revs here b/c they are an internal api
% returns 404 if there is no doc with DocId
- handle_doc_show(Req, Db, DDoc, ShowName, Doc);
+ handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId);
handle_doc_show_req(#httpd{
path_parts=[_, _, _, _, ShowName, DocId|Rest]
}=Req, Db, DDoc) ->
DocParts = [DocId|Rest],
- DocId1 = string:join([?b2l(P)|| P <- DocParts], "/"),
-
+ DocId1 = ?l2b(string:join([?b2l(P)|| P <- DocParts], "/")),
+
% open the doc
- Doc = couch_httpd_db:couch_doc_open(Db, ?l2b(DocId1), nil, [conflicts]),
+ Doc = maybe_open_doc(Db, DocId1),
+
% we don't handle revs here b/c they are an internal api
- % returns 404 if there is no doc with DocId
- handle_doc_show(Req, Db, DDoc, ShowName, Doc);
+ % pass 404 docs to the show function
+ handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId1);
handle_doc_show_req(#httpd{
path_parts=[_, _, _, _, ShowName]
@@ -59,10 +68,13 @@ handle_doc_show_req(Req, _Db, _DDoc) ->
send_error(Req, 404, <<"show_error">>, <<"Invalid path.">>).
handle_doc_show(Req, Db, DDoc, ShowName, Doc) ->
+ handle_doc_show(Req, Db, DDoc, ShowName, Doc, null).
+
+handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId) ->
% get responder for ddoc/showname
CurrentEtag = show_etag(Req, Doc, DDoc, []),
couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
- JsonReq = couch_httpd_external:json_req_obj(Req, Db),
+ JsonReq = couch_httpd_external:json_req_obj(Req, Db, DocId),
JsonDoc = couch_query_servers:json_doc(Doc),
[<<"resp">>, ExternalResp] =
couch_query_servers:ddoc_prompt(DDoc, [<<"shows">>, ShowName], [JsonDoc, JsonReq]),