Skip to content

fix(grpc): surface QdrantClientResourceExhaustedError with full retry-after - #175

Open
jackiectl2 wants to merge 1 commit into
qdrant:masterfrom
jackiectl2:fix/grpc-retry-after
Open

jackiectl2 wants to merge 1 commit into
qdrant:masterfrom
jackiectl2:fix/grpc-retry-after

Conversation

@jackiectl2

Copy link
Copy Markdown

What

The gRPC client's ResourceExhausted handling (added in #95) never reaches users in a usable form:

  1. error.metadata is a Headers object, so error.metadata.get('retry-after')?.[0] keeps only the first character of the value ("15" → retry_after === 1).
  2. QdrantClientResourceExhaustedError overrides name, so connect's ConnectError[Symbol.hasInstance] no longer recognizes it and ConnectError.from() wraps it in a new Code.Unknown error. Callers get [unknown] [resource_exhausted] ... and the real error only via cause.
  3. Because the class inherits ConnectError's static Symbol.hasInstance, err instanceof QdrantClientResourceExhaustedError is true for any ConnectError.

Changes

  • Read the full retry-after value.
  • Keep the base ConnectError name so connect passes the error through unchanged (code stays ResourceExhausted).
  • Restore the normal prototype-chain instanceof check on the subclass.

The REST client has the same ?.[0] pattern; that line is already changed in #128, so this PR only touches the gRPC package.

Testing

  • New packages/js-client-grpc/tests/unit/api-client.test.ts runs createApis against an in-process connect server (no Qdrant needed): ResourceExhausted with retry-after: 15 now yields QdrantClientResourceExhaustedError with code 8 and retry_after 15, and a NotFound error is not an instance of it. Both tests fail without the fix.
  • pnpm -r pre-check passes locally (Node 22). Integration tests were not run locally (they need a Qdrant server).

I did not bump versions or CHANGELOG since recent fix PRs leave that to the release PR; happy to add an entry if preferred.

…-after

The gRPC ResourceExhausted interceptor never delivered a usable
QdrantClientResourceExhaustedError:

- `error.metadata` is a `Headers` object, so `get('retry-after')?.[0]`
  took only the first character of the value ("15" became 1).
- The error set its own `name`, so connect no longer recognized it as a
  ConnectError and wrapped it into a new `Code.Unknown` ConnectError
  (the real error was only reachable via `cause`).
- It inherited ConnectError's `Symbol.hasInstance`, so
  `err instanceof QdrantClientResourceExhaustedError` was true for any
  ConnectError.

Read the full header value, keep the base `ConnectError` name so connect
passes the error through, and restore the prototype chain `instanceof`
check. Add unit tests against an in-process connect server.

Signed-off-by: Tianlang (Jackie) Chen <305351710+jackiectl2@users.noreply.github.com>
@jackiectl2

Copy link
Copy Markdown
Author

The failing check is the Node packages audit step (pnpm audit --prod), which only looks at the lockfile. This PR doesn't touch any dependencies, so it should fail the same way on master until the advisory is resolved there. Happy to rebase once that lands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant