Problem/Motivation
Vector indexing in ai_vdb_provider_milvus runs inside Drupal's entity lifecycle. Whenever a node is created, updated, translated, or deleted, the provider calls MilvusV2::makeRequest() to insert or remove vectors.
When the Milvus server is unreachable:
makeRequest()had no exception handling, so Guzzle'sConnectExceptionpropagated uncaught and unlogged.- The timeouts were set to
120seconds across the board (connect_timeout,read_timeout,timeout), so every request to a dead host blocked for up to two minutes before failing. MilvusProvider::insertIntoCollection()threw\Exception("Failed to record vector.")on failure, and the search/query/delete paths let exceptions propagate as well.
Because these calls happen during entity save/delete, the uncaught exception aborted the surrounding operation. The result:
- Creating or deleting node translations (and other content operations) failed entirely whenever Milvus was down, even though the content operation itself had nothing to do with the vector database.
- Milvus being unavailable effectively blocked normal content editing, with users hanging for ~2 minutes before hitting an error.
Steps to reproduce
- Configure the module against a Milvus server.
- Stop Milvus / point it at an unreachable host.
- Try to create or delete a node translation (or save any indexed node).
- Observe the request hangs for ~120s and then fails with an uncaught exception, aborting the entity operation.
Proposed resolution
- Fail fast on connect, but don't cut off legitimate work. Lower
connect_timeoutto30so an unreachable/misconfigured host is detected quickly, while loweringread_timeoutandtimeoutfrom120to60so large inserts, index builds, and searches aren't killed mid-flight and mistaken for connection failures.read_timeoutis retained to guard against a server that accepts the connection but stalls while sending the response. - Catch and log connection/request errors in
MilvusV2::makeRequest()(ConnectException,RequestException, generic\Exception), including host and operation (path) context, then re-throw so callers can decide how to react.MilvusV2now usesLoggerChannelTrait. - Make callers resilient. Each caller wraps its client call in a try/catch and degrades gracefully instead of aborting the surrounding entity/content operation:
insertIntoCollection(): on exception, log andreturn; alsoreturngracefully (instead of throwing"Failed to record vector.") when the response has nocode, since that indicates a caught connection error.deleteFromCollection(): on exception, log and return.query()andsearch(): on exception, log and return an empty array.- Config form (
validateConfigurationForm()/buildConfigurationForm()): on exception fromdescribeCollection(), build a sentinel['code' => -1]result locally and handle it (see UI changes below).
- Fix incorrect provider labels. Correct the validation message that referenced "Pinecone" to reference "Milvus".
Remaining tasks
- Review + commit.
User interface changes
On the provider config form, an unreachable server now produces a clear validation error on the server field ("Could not connect to the Milvus server. Please check the server address and port.") instead of a hang followed by a WSOD. The previous validation message that incorrectly mentioned "Pinecone" now correctly refers to "Milvus".
API changes
MilvusV2::makeRequest() now logs connection/request failures (ConnectException, RequestException, generic \Exception) with host and operation context before re-throwing; its return type and success behaviour are unchanged. It does not return a sentinel payload. Instead, exception handling now lives in the callers: the config-form validation converts a caught exception into a local ['code' => -1] sentinel to trigger a form error, while insertIntoCollection(), deleteFromCollection(), query(), and search() catch, log, and degrade gracefully (returning early or returning an empty array) so a Milvus outage no longer aborts entity operations.
Data model changes
None.
Issue fork ai_vdb_provider_milvus-3608584
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
remco hoeneveld commentedComment #3
remco hoeneveld commentedComment #4
remco hoeneveld commentedComment #5
remco hoeneveld commentedComment #7
remco hoeneveld commentedComment #8
remco hoeneveld commented