Preserve Qdrant 4xx on the Vision gateway and stop leaking upstream errors.

Map Qdrant 400-499 through as the same status with a short public detail, and keep 5xx and transport failures as sanitized 502. CLIP and other services still use the old helper default.
This commit is contained in:
2026-08-25 07:58:48 +02:00
parent bd0abab759
commit 1713f0ff79
3 changed files with 505 additions and 49 deletions
@@ -0,0 +1,39 @@
# M12.5B — Qdrant HTTP Semantics and Safe Vision Gateway Errors
## Old behavior
Qdrant 4xx (including 422 for `limit > 100`) was rewritten to **Gateway 502**. Public `detail` included the internal URL and raw downstream body.
## New behavior (Qdrant routes only)
| Downstream | Gateway |
| --- | --- |
| 2xx | unchanged JSON |
| 400–499 | **same status**, `detail`: `Vector service rejected the request.` |
| 500–599 | **502**, `detail`: `Vector service unavailable.` |
| transport failure | **502**, sanitized |
| 2xx non-JSON | **502**, sanitized |
CLIP / BLIP / YOLO / Maturity / Card Renderer / LLM still use the previous helper default (`preserve_client_errors=False`).
## Scope
Opt-in via `preserve_client_errors=True, upstream_name="qdrant"` on Qdrant `_post_json` / `_post_file` / `_get_json` / `_delete_json` calls only.
## Deploy (do not run unless requested)
```bash
cd /opt/docker/vision
docker compose build gateway
docker compose up -d --no-deps gateway
```
Do not `docker compose down`. Do not recreate qdrant-svc.
## Rollback
Restore previous `gateway/main.py`, then the same build + `--no-deps gateway` up.
## Acceptance (read-only)
`POST /vectors/search` `limit=100` → **200**. `limit=101` → **422** (not 502). Body must not contain `qdrant-svc` or Qdrant validation JSON.