This is an automated email from the ASF dual-hosted git repository.
jiahuili430 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/main by this push:
new 8b01166db Add guards to `fabric:design_docs/1` to prevent
function_clause error
8b01166db is described below
commit 8b01166db1e7a36a60ada101492c77b99d85b0aa
Author: Jiahui Li <[email protected]>
AuthorDate: Fri May 30 21:42:08 2025 -0500
Add guards to `fabric:design_docs/1` to prevent function_clause error
When a node is down, `fabric:design_docs/1` will return
`{ok, {nodedown, <<"progress not possible">>}}` instead
of a list of design docs. So added some guards for this
function.
In `ddoc_cache_entry_validation_funs.erl`, we cannot use
an empty list because we need to use the VDU function to
validate the document before updating it, so we raise an
error here.
Error log:
```
exit value:#012{
{function_clause, [
{
lists, flatmap_1,
[#Fun<ddoc_cache_entry_validation_funs.0.82671214>, {nodedown,
<<"progress not possible">>}],
[{file, "lists.erl"}, {line, 1578}]
},
{
ddoc_cache_entry_validation_funs, recover, 1,
[{file, "src/ddoc_cache_entry_validation_funs.erl"}, {line, 30}]
},
{
couch_db, '-load_validation_funs/1-fun-0-', 1,
[{file, "src/couch_db.erl"}, {line, 972}]
}
]}
}#012
```
---
src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl | 13 ++++++++++++-
src/dreyfus/src/dreyfus_fabric_cleanup.erl | 9 ++++++++-
src/nouveau/src/nouveau_fabric_cleanup.erl | 9 ++++++++-
src/smoosh/src/smoosh.erl | 9 ++++++++-
4 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl
b/src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl
index 54f5c673f..5d2e50ef2 100644
--- a/src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl
+++ b/src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl
@@ -26,7 +26,18 @@ ddocid(_) ->
no_ddocid.
recover(DbName) ->
- {ok, DDocs} = fabric:design_docs(mem3:dbname(DbName)),
+ %% The VDU function is used to validate documents update before
+ %% storing them in the database.
+ %% Raise an error when invalid instead of returning an empty list.
+ DDocs =
+ case fabric:design_docs(mem3:dbname(DbName)) of
+ {ok, Resp} when is_list(Resp) ->
+ Resp;
+ {ok, Error} ->
+ error(Error);
+ {error, Error} ->
+ error(Error)
+ end,
Funs = lists:flatmap(
fun(DDoc) ->
case couch_doc:get_validate_doc_fun(DbName, DDoc) of
diff --git a/src/dreyfus/src/dreyfus_fabric_cleanup.erl
b/src/dreyfus/src/dreyfus_fabric_cleanup.erl
index e2710744d..86960812d 100644
--- a/src/dreyfus/src/dreyfus_fabric_cleanup.erl
+++ b/src/dreyfus/src/dreyfus_fabric_cleanup.erl
@@ -21,7 +21,14 @@
-export([go/1]).
go(DbName) ->
- {ok, DesignDocs} = fabric:design_docs(DbName),
+ DesignDocs =
+ case fabric:design_docs(DbName) of
+ {ok, DDocs} when is_list(DDocs) ->
+ DDocs;
+ Else ->
+ couch_log:debug("Invalid design docs: ~p~n", [Else]),
+ []
+ end,
ActiveSigs = lists:usort(
lists:flatmap(
fun active_sigs/1,
diff --git a/src/nouveau/src/nouveau_fabric_cleanup.erl
b/src/nouveau/src/nouveau_fabric_cleanup.erl
index cd4128fb1..ea1e28eb3 100644
--- a/src/nouveau/src/nouveau_fabric_cleanup.erl
+++ b/src/nouveau/src/nouveau_fabric_cleanup.erl
@@ -22,7 +22,14 @@
-export([go/1]).
go(DbName) ->
- {ok, DesignDocs} = fabric:design_docs(DbName),
+ DesignDocs =
+ case fabric:design_docs(DbName) of
+ {ok, DDocs} when is_list(DDocs) ->
+ DDocs;
+ Else ->
+ couch_log:debug("Invalid design docs: ~p~n", [Else]),
+ []
+ end,
ActiveSigs =
lists:usort(
lists:flatmap(
diff --git a/src/smoosh/src/smoosh.erl b/src/smoosh/src/smoosh.erl
index 68e8d1828..00dc186ca 100644
--- a/src/smoosh/src/smoosh.erl
+++ b/src/smoosh/src/smoosh.erl
@@ -64,7 +64,14 @@ fold_local_shards(Fun, Acc0) ->
enqueue_views(ShardName) ->
DbName = mem3:dbname(ShardName),
- {ok, DDocs} = fabric:design_docs(DbName),
+ DDocs =
+ case fabric:design_docs(DbName) of
+ {ok, Resp} when is_list(Resp) ->
+ Resp;
+ Else ->
+ couch_log:debug("Invalid design docs: ~p~n", [Else]),
+ []
+ end,
[sync_enqueue({ShardName, id(DDoc)}) || DDoc <- DDocs].
id(#doc{id = Id}) ->