You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2023/07/13 18:04:36 UTC
[couchdb] 01/01: [WIP] Do not skip over uknown 400 error on replication doc PUT
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch replicator-skip-explicit-4xx-errors-only
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit b53855778133a43cf1b22604a82228df0b979d7b
Author: Nick Vatamaniuc <va...@gmail.com>
AuthorDate: Thu Jul 13 14:02:55 2023 -0400
[WIP] Do not skip over uknown 400 error on replication doc PUT
Issue: https://github.com/apache/couchdb/issues/4676
---
src/chttpd/src/chttpd_db.erl | 3 +-
.../src/couch_replicator_worker.erl | 79 ++++++++++++----------
2 files changed, 47 insertions(+), 35 deletions(-)
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index e2de301b2..8e377878d 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -1138,7 +1138,8 @@ db_doc_req(#httpd{method = 'PUT', user_ctx = Ctx} = Req, Db, DocId) ->
UpdateType
),
WaitFun(),
- send_json(Req, HttpCode, RespHeaders1, RespBody)
+ %send_json(Req, HttpCode, RespHeaders1, RespBody)
+ send_json(Req, 418, RespHeaders1, RespBody)
catch
throw:Err ->
% Document rejected by a validate_doc_update function.
diff --git a/src/couch_replicator/src/couch_replicator_worker.erl b/src/couch_replicator/src/couch_replicator_worker.erl
index 46e4a6e94..0fb7057eb 100644
--- a/src/couch_replicator/src/couch_replicator_worker.erl
+++ b/src/couch_replicator/src/couch_replicator_worker.erl
@@ -583,44 +583,55 @@ handle_flush_docs_result({error, {bulk_docs_failed, _, _} = Err}, _, _) ->
flush_doc(Target, #doc{id = Id, revs = {Pos, [RevId | _]}} = Doc) ->
try couch_replicator_api_wrap:update_doc(Target, Doc, [], ?REPLICATED_CHANGES) of
- {ok, _} ->
- ok;
- Error ->
- couch_log:error(
- "Replicator: error writing document `~s` to `~s`: ~s",
- [Id, couch_replicator_api_wrap:db_uri(Target), couch_util:to_binary(Error)]
- ),
- Error
+ {ok, _} -> ok;
+ Error -> handle_doc_write_error(Error, Target, Id, Pos, RevId)
catch
- throw:{missing_stub, _} = MissingStub ->
- throw(MissingStub);
throw:{Error, Reason} ->
- couch_log:error(
- "Replicator: couldn't write document `~s`, revision `~s`,"
- " to target database `~s`. Error: `~s`, reason: `~s`.",
- [
- Id,
- couch_doc:rev_to_str({Pos, RevId}),
- couch_replicator_api_wrap:db_uri(Target),
- to_binary(Error),
- to_binary(Reason)
- ]
- ),
- {error, Error};
- throw:Err ->
- couch_log:error(
- "Replicator: couldn't write document `~s`, revision `~s`,"
- " to target database `~s`. Error: `~s`.",
- [
- Id,
- couch_doc:rev_to_str({Pos, RevId}),
- couch_replicator_api_wrap:db_uri(Target),
- to_binary(Err)
- ]
- ),
- {error, Err}
+ handle_doc_write_error({Error, Reason}, Target, Id, Pos, RevId)
end.
+% In most cases we fail the replication job by re-throwing the error.
+% The only exceptions are
+% 401 : unauthorized
+% 403 : forbidden
+% 413 : request_body_too_large
+%
+handle_doc_write_error({missing_stub, _} = MissingStub, _, _, _, _) ->
+ throw(MissingStub);
+handle_doc_write_error({error, request_body_too_large} = Error, Target, Id, _, _) ->
+ couch_log:error(
+ "Replicator: skipping writing document `~s` to `~s` : request_body_too_large.",
+ [Id, couch_replicator_api_wrap:db_uri(Target)]
+ ),
+ Error;
+handle_doc_write_error({Error, Reason}, Target, Id, Pos, RevId) when
+ Error == unauthorized orelse Error == forbidden
+->
+ couch_log:error(
+ "Replicator: skipping writing document `~s`, revision `~s`,"
+ " to target database `~s`. Error: `~s`, reason: `~s`.",
+ [
+ Id,
+ couch_doc:rev_to_str({Pos, RevId}),
+ couch_replicator_api_wrap:db_uri(Target),
+ to_binary(Error),
+ to_binary(Reason)
+ ]
+ ),
+ {error, Error};
+handle_doc_write_error(Err, Target, Id, Pos, RevId) ->
+ couch_log:error(
+ "Replicator: error writting document `~s`, revision `~s`,"
+ " to target database `~s`. Error: `~s`.",
+ [
+ Id,
+ couch_doc:rev_to_str({Pos, RevId}),
+ couch_replicator_api_wrap:db_uri(Target),
+ to_binary(Err)
+ ]
+ ),
+ throw(Err).
+
find_missing(DocInfos, Target, Parent, #fetch_stats{} = St) ->
{IdRevs, AllCount} = lists:foldr(
fun