summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/couchdb/couch_httpd.erl26
-rw-r--r--src/couchdb/couch_httpd_show.erl83
-rw-r--r--src/couchdb/couch_httpd_view.erl26
3 files changed, 62 insertions, 73 deletions
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,
- "<html><body><h2>Error: ", ErrorStr, "</h2>",
- "<pre>Reason: ", ReasonStr, "</pre>", $\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).