From 468cb2fd2b15ab5046768ab379abdb3226dd0ddd Mon Sep 17 00:00:00 2001 From: Alexander Fenster Date: Tue, 26 Jul 2022 12:48:08 -0700 Subject: [PATCH] fix: return error if GetOperation call fails --- src/longRunningCalls/longrunning.ts | 19 ++++++++---- test/unit/longrunning.ts | 45 +++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/longRunningCalls/longrunning.ts b/src/longRunningCalls/longrunning.ts index 8b731a5e2..e061ccf99 100644 --- a/src/longRunningCalls/longrunning.ts +++ b/src/longRunningCalls/longrunning.ts @@ -189,11 +189,20 @@ export class Operation extends EventEmitter { this._callOptions! ); - const noCallbackPromise = this.currentCallPromise_!.then(responses => { - self.latestResponse = responses[0] as LROOperation; - self._unpackResponse(responses[0] as LROOperation, callback); - return promisifyResponse()!; - }); + const noCallbackPromise = this.currentCallPromise_.then( + responses => { + self.latestResponse = responses[0] as LROOperation; + self._unpackResponse(responses[0] as LROOperation, callback); + return promisifyResponse()!; + }, + (err: Error) => { + if (callback) { + callback(err); + return; + } + return Promise.reject(err); + } + ); if (!callback) { return noCallbackPromise as Promise<{}>; diff --git a/test/unit/longrunning.ts b/test/unit/longrunning.ts index 03580f670..d6a25c3b6 100644 --- a/test/unit/longrunning.ts +++ b/test/unit/longrunning.ts @@ -103,10 +103,11 @@ describe('longrunning', () => { let remainingCalls = opts.expectedCalls ? opts.expectedCalls : null; const cancelGetOperationSpy = sinon.spy(); const getOperationSpy = sinon.spy(() => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let resolver: any; - const promise = new Promise(resolve => { + let resolver: (value: unknown) => void = () => {}; + let rejecter: (value: unknown) => void = () => {}; + const promise = new Promise((resolve, reject) => { resolver = resolve; + rejecter = reject; }); // eslint-disable-next-line @typescript-eslint/no-explicit-any (promise as any).cancel = cancelGetOperationSpy; @@ -114,6 +115,8 @@ describe('longrunning', () => { if (remainingCalls && remainingCalls > 1) { resolver([PENDING_OP]); --remainingCalls; + } else if (opts.reject) { + rejecter(opts.reject); } else if (!opts.dontResolve) { resolver([opts.finalOperation || SUCCESSFUL_OP]); } @@ -602,6 +605,42 @@ describe('longrunning', () => { }); }); + it('getOperation failure emits an error', done => { + const func = ( + argument: {}, + metadata: {}, + options: {}, + callback: Function + ) => { + callback(null, PENDING_OP); + }; + const expectedCalls = 3; + const googleError = new GoogleError('GetOperation call failed'); + googleError.code = 8; + googleError.statusDetails = 'Quota exceeded'; + const client = mockOperationsClient({ + expectedCalls, + reject: googleError, + }); + const apiCall = createApiCall(func, client); + apiCall({}) + .then(responses => { + const operation = responses[0] as longrunning.Operation; + operation.on('complete', () => { + done(new Error('Should not get here.')); + }); + operation.on('error', err => { + assert.strictEqual(client.getOperation.callCount, expectedCalls); + assert.strictEqual(err.code, googleError.code); + assert.strictEqual(err.message, googleError.message); + done(); + }); + }) + .catch(err => { + done(err); + }); + }); + it('emits progress on updated operations.', done => { const func = ( argument: {},