|
@@ -859,6 +859,11 @@ grpc::Status DatabaseGrpcImpl::SimilaritySearch(
|
|
|
if (!collection.empty() && collection[0] != '_'
|
|
if (!collection.empty() && collection[0] != '_'
|
|
|
&& service_.mirrorHealthy() && service_.mirrorDriftCount() == 0) {
|
|
&& service_.mirrorHealthy() && service_.mirrorDriftCount() == 0) {
|
|
|
if (auto* ds = service_.docStore()) {
|
|
if (auto* ds = service_.docStore()) {
|
|
|
|
|
+ // Hoisted to try-block scope so the catch block can prefer
|
|
|
|
|
+ // INVALID_ARGUMENT over INTERNAL when a dim mismatch was
|
|
|
|
|
+ // observed before some unrelated throw fired.
|
|
|
|
|
+ bool dim_mismatch = false;
|
|
|
|
|
+ std::string mismatch_msg;
|
|
|
try {
|
|
try {
|
|
|
// Pre-compute query norm once outside the iteration.
|
|
// Pre-compute query norm once outside the iteration.
|
|
|
const float queryNorm =
|
|
const float queryNorm =
|
|
@@ -878,8 +883,6 @@ grpc::Status DatabaseGrpcImpl::SimilaritySearch(
|
|
|
std::priority_queue<Scored, std::vector<Scored>,
|
|
std::priority_queue<Scored, std::vector<Scored>,
|
|
|
decltype(cmp)> heap(cmp);
|
|
decltype(cmp)> heap(cmp);
|
|
|
size_t expectedDim = queryVec.size();
|
|
size_t expectedDim = queryVec.size();
|
|
|
- bool dim_mismatch = false;
|
|
|
|
|
- std::string mismatch_msg;
|
|
|
|
|
|
|
|
|
|
ds->scan_vectors(collection,
|
|
ds->scan_vectors(collection,
|
|
|
[&](std::string_view id, const float* data,
|
|
[&](std::string_view id, const float* data,
|
|
@@ -952,7 +955,16 @@ grpc::Status DatabaseGrpcImpl::SimilaritySearch(
|
|
|
// INVALID_ARGUMENT.
|
|
// INVALID_ARGUMENT.
|
|
|
throw;
|
|
throw;
|
|
|
} catch (const std::exception& e) {
|
|
} catch (const std::exception& e) {
|
|
|
- // v2.1.1 — no defensive fallback on throw; surface INTERNAL.
|
|
|
|
|
|
|
+ // v2.2.1 — if the scan saw a dimension mismatch BEFORE
|
|
|
|
|
+ // the throw fired (e.g. bad_alloc on the heap), the
|
|
|
|
|
+ // root cause is the caller's wrong-dimension query, not
|
|
|
|
|
+ // the storage error. Prefer INVALID_ARGUMENT over the
|
|
|
|
|
+ // less-actionable INTERNAL so operators see the real
|
|
|
|
|
+ // cause.
|
|
|
|
|
+ if (dim_mismatch) {
|
|
|
|
|
+ return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
|
|
|
|
|
+ mismatch_msg);
|
|
|
|
|
+ }
|
|
|
spdlog::error("v2.1 SimilaritySearch LMDB scan failed coll={}: {}",
|
|
spdlog::error("v2.1 SimilaritySearch LMDB scan failed coll={}: {}",
|
|
|
collection, e.what());
|
|
collection, e.what());
|
|
|
return grpc::Status(grpc::StatusCode::INTERNAL, e.what());
|
|
return grpc::Status(grpc::StatusCode::INTERNAL, e.what());
|