From 3e47bfd6586f42f9fe8e49cea03c4df976c781a1 Mon Sep 17 00:00:00 2001 From: John Christopher Anderson Date: Sat, 18 Apr 2009 20:15:44 +0000 Subject: refactor main.js into many files and improve show/list error handling git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@766383 13f79535-47bb-0310-9956-ffa450edef68 --- src/couchdb/couch_httpd.erl | 26 ++++++------- src/couchdb/couch_httpd_show.erl | 83 +++++++++++++++++++++++----------------- src/couchdb/couch_httpd_view.erl | 26 ++----------- 3 files changed, 62 insertions(+), 73 deletions(-) (limited to 'src/couchdb') diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl index a16f5fdd..5e150055 100644 --- a/src/couchdb/couch_httpd.erl +++ b/src/couchdb/couch_httpd.erl @@ -422,8 +422,8 @@ error_info({Error, Reason}) -> error_info(Error) -> {500, <<"unknown_error">>, couch_util:to_binary(Error)}. -send_error(_Req, {already_sent, _Error}) -> - ok; +send_error(_Req, {already_sent, Resp, _Error}) -> + {ok, Resp}; send_error(Req, Error) -> {Code, ErrorStr, ReasonStr} = error_info(Error), @@ -447,21 +447,17 @@ send_error(Req, Code, Headers, ErrorStr, ReasonStr) -> {[{<<"error">>, ErrorStr}, {<<"reason">>, ReasonStr}]}). +% give the option for list functions to output html or other raw errors +send_chunked_error(Resp, {_Error, {[{<<"body">>, Reason}]}}) -> + send_chunk(Resp, Reason), + send_chunk(Resp, []); + send_chunked_error(Resp, Error) -> {Code, ErrorStr, ReasonStr} = error_info(Error), - CType = Resp:get_header_value("Content-Type"), - case CType of - "text/html" -> - HtmlError = ?l2b([$\n, - "

Error: ", ErrorStr, "

", - "
Reason: ", ReasonStr, "
", $\n]), - send_chunk(Resp, HtmlError); - _Else -> - JsonError = {[{<<"code">>, Code}, - {<<"error">>, ErrorStr}, - {<<"reason">>, ReasonStr}]}, - send_chunk(Resp, ?l2b([$\n,?JSON_ENCODE(JsonError),$\n])) - end, + JsonError = {[{<<"code">>, Code}, + {<<"error">>, ErrorStr}, + {<<"reason">>, ReasonStr}]}, + send_chunk(Resp, ?l2b([$\n,?JSON_ENCODE(JsonError),$\n])), send_chunk(Resp, []). send_redirect(Req, Path) -> diff --git a/src/couchdb/couch_httpd_show.erl b/src/couchdb/couch_httpd_show.erl index 5aed8971..21611262 100644 --- a/src/couchdb/couch_httpd_show.erl +++ b/src/couchdb/couch_httpd_show.erl @@ -19,7 +19,7 @@ -import(couch_httpd, [send_json/2,send_json/3,send_json/4,send_method_not_allowed/2, - start_json_response/2,send_chunk/2, + start_json_response/2,send_chunk/2,send_chunked_error/2, start_chunked_response/3, send_error/4]). handle_doc_show_req(#httpd{ @@ -132,24 +132,30 @@ make_map_start_resp_fun(QueryServer, Req, Db, CurrentEtag) -> make_map_send_row_fun(QueryServer, Req) -> fun(Resp, Db2, {{Key, DocId}, Value}, RowFront, _IncludeDocs) -> - JsonResp = couch_query_servers:render_list_row(QueryServer, - Req, Db2, {{Key, DocId}, Value}), - #extern_resp_args{ - stop = StopIter, - data = RowBody - } = couch_httpd_external:parse_external_response(JsonResp), - case StopIter of - true -> stop; - _ -> - RowFront2 = case RowFront of - nil -> []; - _ -> RowFront - end, - Chunk = RowFront2 ++ binary_to_list(RowBody), - case Chunk of - [] -> {ok, Resp}; - _ -> send_chunk(Resp, Chunk) + try + JsonResp = couch_query_servers:render_list_row(QueryServer, + Req, Db2, {{Key, DocId}, Value}), + #extern_resp_args{ + stop = StopIter, + data = RowBody + } = couch_httpd_external:parse_external_response(JsonResp), + case StopIter of + true -> stop; + _ -> + RowFront2 = case RowFront of + nil -> []; + _ -> RowFront + end, + Chunk = RowFront2 ++ binary_to_list(RowBody), + case Chunk of + [] -> {ok, Resp}; + _ -> send_chunk(Resp, Chunk) + end end + catch + throw:Error -> + send_chunked_error(Resp, Error), + throw({already_sent, Resp, Error}) end end. @@ -241,24 +247,30 @@ make_reduce_start_resp_fun(QueryServer, Req, Db, CurrentEtag) -> make_reduce_send_row_fun(QueryServer, Req, Db) -> fun(Resp, {Key, Value}, RowFront) -> - JsonResp = couch_query_servers:render_reduce_row(QueryServer, - Req, Db, {Key, Value}), - #extern_resp_args{ - stop = StopIter, - data = RowBody - } = couch_httpd_external:parse_external_response(JsonResp), - RowFront2 = case RowFront of - nil -> []; - _ -> RowFront - end, - case StopIter of - true -> stop; - _ -> - Chunk = RowFront2 ++ binary_to_list(RowBody), - case Chunk of - [] -> {ok, Resp}; - _ -> send_chunk(Resp, Chunk) + try + JsonResp = couch_query_servers:render_reduce_row(QueryServer, + Req, Db, {Key, Value}), + #extern_resp_args{ + stop = StopIter, + data = RowBody + } = couch_httpd_external:parse_external_response(JsonResp), + RowFront2 = case RowFront of + nil -> []; + _ -> RowFront + end, + case StopIter of + true -> stop; + _ -> + Chunk = RowFront2 ++ binary_to_list(RowBody), + case Chunk of + [] -> {ok, Resp}; + _ -> send_chunk(Resp, Chunk) + end end + catch + throw:Error -> + send_chunked_error(Resp, Error), + throw({already_sent, Resp, Error}) end end. @@ -417,3 +429,4 @@ apply_etag({ExternalResponse}, CurrentEtag) -> Field end || Field <- ExternalResponse]} end. + \ No newline at end of file diff --git a/src/couchdb/couch_httpd_view.erl b/src/couchdb/couch_httpd_view.erl index 0348cf8b..8702a3dc 100644 --- a/src/couchdb/couch_httpd_view.erl +++ b/src/couchdb/couch_httpd_view.erl @@ -530,7 +530,7 @@ apply_default_helper_funs(#view_fold_helper_funs{ Helpers#view_fold_helper_funs{ passed_end = PassedEnd2, start_response = StartResp2, - send_row = wrap_for_chunked_errors(SendRow2) + send_row = SendRow2 }. apply_default_helper_funs(#reduce_fold_helper_funs{ @@ -549,7 +549,7 @@ apply_default_helper_funs(#reduce_fold_helper_funs{ Helpers#reduce_fold_helper_funs{ start_response = StartResp2, - send_row = wrap_for_chunked_errors(SendRow2) + send_row = SendRow2 }. make_passed_end_fun(fwd, EndKey, EndDocId, InclusiveEnd) -> @@ -606,27 +606,7 @@ send_json_reduce_row(Resp, {Key, Value}, RowFront) -> nil -> ",\r\n"; _ -> RowFront end, - send_chunk(Resp, RowFront2 ++ ?JSON_ENCODE({[{key, Key}, {value, Value}]})). - -wrap_for_chunked_errors(Fun) when is_function(Fun, 3)-> - fun(Resp, B, C) -> - try Fun(Resp, B, C) - catch - throw:Error -> - send_chunked_error(Resp, Error), - throw({already_sent, Error}) - end - end; - -wrap_for_chunked_errors(Fun) when is_function(Fun, 5)-> - fun(Resp, B, C, D, E) -> - try Fun(Resp, B, C, D, E) - catch - throw:Error -> - send_chunked_error(Resp, Error), - throw({already_sent, Error}) - end - end. + send_chunk(Resp, RowFront2 ++ ?JSON_ENCODE({[{key, Key}, {value, Value}]})). view_group_etag(Group) -> view_group_etag(Group, nil). -- cgit v1.2.3