Skip to content

Commit 3d5b0f0

Browse files
feat: more information for exceed timeout error (#839)
* more informtion for exceed timeout error * fix * add unit test * feedback * reformat error message * pass api name to create api call * lint * add service name from construction
1 parent 653d327 commit 3d5b0f0

5 files changed

Lines changed: 33 additions & 5 deletions

File tree

packages/packages/google-gax/src/createApiCall.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ export function createApiCall(
8888
return retryable(
8989
func,
9090
thisSettings.retry!,
91-
thisSettings.otherArgs as GRPCCallOtherArgs
91+
thisSettings.otherArgs as GRPCCallOtherArgs,
92+
thisSettings.apiName
9293
);
9394
}
9495
return addTimeoutArg(

packages/packages/google-gax/src/gax.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export interface CallOptions {
124124
bundleOptions?: BundleOptions | null;
125125
isBundling?: boolean;
126126
longrunning?: BackoffSettings;
127+
apiName?: string;
127128
}
128129

129130
export class CallSettings {
@@ -138,6 +139,7 @@ export class CallSettings {
138139
bundleOptions?: BundleOptions | null;
139140
isBundling: boolean;
140141
longrunning?: BackoffSettings;
142+
apiName?: string;
141143

142144
/**
143145
* @param {Object} settings - An object containing parameters of this settings.
@@ -170,6 +172,7 @@ export class CallSettings {
170172
this.isBundling = 'isBundling' in settings ? settings.isBundling! : true;
171173
this.longrunning =
172174
'longrunning' in settings ? settings.longrunning : undefined;
175+
this.apiName = settings.apiName ?? undefined;
173176
}
174177

175178
/**
@@ -193,6 +196,7 @@ export class CallSettings {
193196
let otherArgs = this.otherArgs;
194197
let isBundling = this.isBundling;
195198
let longrunning = this.longrunning;
199+
let apiName = this.apiName;
196200
if ('timeout' in options) {
197201
timeout = options.timeout!;
198202
}
@@ -239,6 +243,9 @@ export class CallSettings {
239243
if ('longrunning' in options) {
240244
longrunning = options.longrunning;
241245
}
246+
if ('apiName' in options) {
247+
apiName = options.apiName;
248+
}
242249

243250
return new CallSettings({
244251
timeout,
@@ -251,6 +258,7 @@ export class CallSettings {
251258
maxResults,
252259
otherArgs,
253260
isBundling,
261+
apiName,
254262
});
255263
}
256264
}
@@ -650,14 +658,15 @@ export function constructSettings(
650658
)!
651659
);
652660
}
653-
661+
const apiName = serviceName;
654662
defaults[jsName] = new CallSettings({
655663
timeout,
656664
retry,
657665
bundleOptions: bundlingConfig
658666
? createBundleOptions(bundlingConfig)
659667
: null,
660668
otherArgs,
669+
apiName,
661670
});
662671
}
663672

packages/packages/google-gax/src/normalCalls/retries.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ import {addTimeoutArg} from './timeout';
4545
export function retryable(
4646
func: GRPCCall,
4747
retry: RetryOptions,
48-
otherArgs: GRPCCallOtherArgs
48+
otherArgs: GRPCCallOtherArgs,
49+
apiName?: string
4950
): SimpleCallbackFunction {
5051
const delayMult = retry.backoffSettings.retryDelayMultiplier;
5152
const maxDelay = retry.backoffSettings.maxRetryDelayMillis;
@@ -81,7 +82,7 @@ export function retryable(
8182
timeoutId = null;
8283
if (deadline && now.getTime() >= deadline) {
8384
const error = new GoogleError(
84-
'Retry total timeout exceeded before any response was received'
85+
`Total timeout of API ${apiName} exceeded ${retry.backoffSettings.totalTimeoutMillis} milliseconds before any response was received.`
8586
);
8687
error.code = Status.DEADLINE_EXCEEDED;
8788
callback(error);

packages/packages/google-gax/test/unit/apiCallable.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,9 @@ describe('Promise', () => {
213213

214214
describe('retryable', () => {
215215
const retryOptions = utils.createRetryOptions(0, 0, 0, 0, 0, 0, 100);
216-
const settings = {settings: {timeout: 0, retry: retryOptions}};
216+
const settings = {
217+
settings: {timeout: 0, retry: retryOptions, apiName: 'TestApi'},
218+
};
217219

218220
it('retries the API call', done => {
219221
let toAttempt = 3;
@@ -364,6 +366,20 @@ describe('retryable', () => {
364366
});
365367
});
366368

369+
it('retry fails for exceeding total timeout', done => {
370+
const spy = sinon.spy(fail);
371+
const apiCall = createApiCall(spy, settings);
372+
apiCall({}, undefined, err => {
373+
assert.ok(err instanceof GoogleError);
374+
assert.strictEqual(
375+
err.message,
376+
'Total timeout of API TestApi exceeded 100 milliseconds before any response was received.'
377+
);
378+
assert.strictEqual(err!.code, status.DEADLINE_EXCEEDED);
379+
done();
380+
});
381+
});
382+
367383
// maxRetries is unsupported, and intended for internal use only.
368384
it('errors when totalTimeoutMillis and maxRetries set', done => {
369385
const maxRetries = 5;

packages/packages/google-gax/test/unit/gax.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ describe('gax construct settings', () => {
110110
);
111111
let settings = defaults.bundlingMethod;
112112
assert.strictEqual(settings.timeout, 40000);
113+
assert.strictEqual(settings.apiName, SERVICE_NAME);
113114
expectRetryOptions(settings.retry);
114115
assert.deepStrictEqual(settings.retry.retryCodes, [1, 2]);
115116
assert.strictEqual(settings.otherArgs, otherArgs);

0 commit comments

Comments
 (0)