diff --git a/__tests__/integration/query.test.ts b/__tests__/integration/query.test.ts index 1641a226..9da5bd2d 100644 --- a/__tests__/integration/query.test.ts +++ b/__tests__/integration/query.test.ts @@ -37,6 +37,7 @@ const dummyResponse: HTTPResponse = { storage_bytes_read: 0, storage_bytes_write: 0, contention_retries: 0, + rate_limits_hit: ["read", "write", "compute"], }, }), headers: {}, @@ -62,6 +63,7 @@ describe("query", () => { expect(result.stats?.compute_ops).toBeDefined(); expect(result.stats?.contention_retries).toBeDefined(); expect(result.stats?.query_time_ms).toBeDefined(); + expect(result.stats?.rate_limits_hit).toBeDefined(); expect(result.stats?.read_ops).toBeDefined(); expect(result.stats?.storage_bytes_read).toBeDefined(); expect(result.stats?.storage_bytes_write).toBeDefined(); diff --git a/src/errors.ts b/src/errors.ts index 861559bf..38136ff2 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -2,6 +2,7 @@ import type { ConstraintFailure, QueryFailure, QueryInfo, + QueryStats, QueryValue, } from "./wire-protocol"; @@ -226,8 +227,11 @@ export class ThrottlingError extends ServiceError { export class QueryTimeoutError extends ServiceError { /** * Statistics regarding the query. + * + * TODO: Deprecate this `stats` field. All `ServiceError`s already provide + * access to stats through `queryInfo.stats` */ - readonly stats?: { [key: string]: number }; + readonly stats?: QueryStats; constructor(failure: QueryFailure, httpStatus?: number) { super(failure, httpStatus); diff --git a/src/wire-protocol.ts b/src/wire-protocol.ts index 0798a5c2..325f672c 100644 --- a/src/wire-protocol.ts +++ b/src/wire-protocol.ts @@ -133,6 +133,11 @@ export type QueryStats = { contention_retries: number; /** The number query attempts made due to retryable errors. */ attempts: number; + /** + * A list of rate limits hit. + * Included with QueryFailure responses when the query is rate limited. + */ + rate_limits_hit?: ("read" | "write" | "compute")[]; }; export type QueryInfo = {