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}) ->

Reply via email to