This is an automated email from the ASF dual-hosted git repository.

jaydoane pushed a commit to branch dreyfus-fabric-search-handle-timeout
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit e014b6498f832a0f59ecb54f47ec3ce56c9c4fe5
Author: Jay Doane <[email protected]>
AuthorDate: Thu Oct 2 13:57:54 2025 -0700

    Handle timeout in `dreyfus_fabric_search:go`
    
    Currently, receiving a timeout from `rexi_util:recv` exposes internal
    state in the error message, and obscures the timeout:
    ```
    
    ❯ curl -u adm:pass $D1/db-e3/_find -d '{"use_index": 
"_design/af381e41784d465bb1349f8378f90bba9c6d252e", "selector": {"x": 
{"$regex": "^(((a+)+)+)+$"}}, "execution_stats": true}' | jq .
    {
      "error": "try_clause",
      "reason": "{timeout,{state,200,relevance,\n                
{top_docs,undefined,0,[],undefined,undefined},\n                
[{{shard,<<\"shards/00000000-7fffffff/db-e3.1757182851\">>,\n                   
      '[email protected]',<<\"db-e3\">>,\n                         
[0,2147483647],\n                         
#Ref<0.4061688246.3678666753.76196>,\n                         [{props,[]}]},\n 
                 nil},\n                 
{{shard,<<\"shards/00000000-7fffffff/db-e3.1757182851\"> [...]
      "ref": 2182595996
    }
    ```
    
    With this patch, a timeout is handled more elegantly:
    ```
    ❯ curl -u adm:pass $D1/db-e3/_find -d '{"use_index": 
"_design/af381e41784d465bb1349f8378f90bba9c6d252e", "selector": {"x": 
{"$regex": "^(((a+)+)+)+$"}}, "execution_stats": true}' | jq .
    {
      "error": "text_search_error",
      "reason": "timeout",
      "ref": 68970337
    }
    ```
---
 src/dreyfus/src/dreyfus_fabric_search.erl |  4 +++-
 test/elixir/test/search_test.exs          | 28 ++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/dreyfus/src/dreyfus_fabric_search.erl 
b/src/dreyfus/src/dreyfus_fabric_search.erl
index 75a2a5a3b..0d07db6ef 100644
--- a/src/dreyfus/src/dreyfus_fabric_search.erl
+++ b/src/dreyfus/src/dreyfus_fabric_search.erl
@@ -142,7 +142,9 @@ go(DbName, DDoc, IndexName, QueryArgs, Counters, Bookmark, 
RingOpts) ->
                     {ok, Bookmark1, TotalHits, Hits1, Counts, Ranges}
             end;
         {error, Reason} ->
-            {error, Reason}
+            {error, Reason};
+        {timeout, _State} ->
+            {error, timeout}
     after
         rexi_monitor:stop(RexiMon),
         fabric_streams:cleanup(Workers)
diff --git a/test/elixir/test/search_test.exs b/test/elixir/test/search_test.exs
index edf08f30d..035e61b5f 100644
--- a/test/elixir/test/search_test.exs
+++ b/test/elixir/test/search_test.exs
@@ -290,4 +290,32 @@ defmodule SearchTest do
     %{:body => %{"ranges" => ranges}} = resp
     assert ranges == %{"price" => %{}}
   end
+
+  @tag :with_db
+  test "timeouts do not expose internal state", context do
+    db_name = context[:db_name]
+    create_search_docs(db_name)
+    create_ddoc(db_name)
+
+    config = [
+      %{
+        :section => "fabric",
+        :key => "search_timeout",
+        :value => "0"
+      }
+    ]
+
+    run_on_modified_server(config, fn ->
+      url = "/#{db_name}/_design/inventory/_search/fruits"
+      resp = Couch.get(url, query: %{q: "*:*", include_docs: true})
+      assert resp.status_code == 500
+
+      %{
+        :body => %{
+          "error" => "timeout",
+          "reason" => "The request could not be processed in a reasonable 
amount of time."
+        }
+      } = resp
+    end)
+  end
 end

Reply via email to