From 50d1b4d8241444773b2cddb1e4bc2f08838dc7d5 Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Mon, 10 May 2021 11:05:53 +0000 Subject: [PATCH 01/10] fix: increasing timeout, closes #657 --- src/SASViyaApiClient.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 5150524..d2dea33 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -1103,7 +1103,7 @@ export class SASViyaApiClient { const { result: state } = await this.requestClient .get( - `${this.serverUrl}${stateLink.href}?_action=wait&wait=30`, + `${this.serverUrl}${stateLink.href}?_action=wait&wait=300`, accessToken, 'text/plain', {}, @@ -1130,7 +1130,7 @@ export class SASViyaApiClient { if (stateLink) { const { result: jobState } = await this.requestClient .get( - `${this.serverUrl}${stateLink.href}?_action=wait&wait=30`, + `${this.serverUrl}${stateLink.href}?_action=wait&wait=300`, accessToken, 'text/plain', {}, From 67c7147e62d1fb111648dbdcafea4435fe443b71 Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Mon, 10 May 2021 11:13:39 +0000 Subject: [PATCH 02/10] fix: lint updates --- src/ContextManager.ts | 4 +--- src/SASViyaApiClient.ts | 23 ++++++++++------------- src/SessionManager.ts | 5 +---- src/job-execution/WebJobExecutor.ts | 6 ++---- src/request/RequestClient.ts | 11 +++++------ src/test/utils/isUrl.spec.ts | 4 ++-- 6 files changed, 21 insertions(+), 32 deletions(-) diff --git a/src/ContextManager.ts b/src/ContextManager.ts index 3c15ff5..eec0dff 100644 --- a/src/ContextManager.ts +++ b/src/ContextManager.ts @@ -314,9 +314,7 @@ export class ContextManager { contextId: string, accessToken?: string ): Promise { - const { - result: context - } = await this.requestClient + const { result: context } = await this.requestClient .get( `${this.serverUrl}/compute/contexts/${contextId}`, accessToken diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index d2dea33..8b526c2 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -594,16 +594,15 @@ export class SASViyaApiClient { } } - const { - result: createFolderResponse - } = await this.requestClient.post( - `/folders/folders?parentFolderUri=${parentFolderUri}`, - { - name: folderName, - type: 'folder' - }, - accessToken - ) + const { result: createFolderResponse } = + await this.requestClient.post( + `/folders/folders?parentFolderUri=${parentFolderUri}`, + { + name: folderName, + type: 'folder' + }, + accessToken + ) // update folder map with newly created folder. await this.populateFolderMap( @@ -875,9 +874,7 @@ export class SASViyaApiClient { throw new Error(`URI of job definition was not found.`) } - const { - result: jobDefinition - } = await this.requestClient + const { result: jobDefinition } = await this.requestClient .get( `${this.serverUrl}${jobDefinitionLink.href}`, accessToken diff --git a/src/SessionManager.ts b/src/SessionManager.ts index 3c780dd..2120471 100644 --- a/src/SessionManager.ts +++ b/src/SessionManager.ts @@ -91,10 +91,7 @@ export class SessionManager { } private async createAndWaitForSession(accessToken?: string) { - const { - result: createdSession, - etag - } = await this.requestClient + const { result: createdSession, etag } = await this.requestClient .post( `${this.serverUrl}/compute/contexts/${ this.currentContext!.id diff --git a/src/job-execution/WebJobExecutor.ts b/src/job-execution/WebJobExecutor.ts index 816c6d7..61f215c 100644 --- a/src/job-execution/WebJobExecutor.ts +++ b/src/job-execution/WebJobExecutor.ts @@ -71,10 +71,8 @@ export class WebJobExecutor extends BaseJobExecutor { } else { // param based approach try { - const { - formData: newFormData, - requestParams: params - } = generateTableUploadForm(formData, data) + const { formData: newFormData, requestParams: params } = + generateTableUploadForm(formData, data) formData = newFormData requestParams = { ...requestParams, ...params } } catch (e) { diff --git a/src/request/RequestClient.ts b/src/request/RequestClient.ts index c55060b..c38d506 100644 --- a/src/request/RequestClient.ts +++ b/src/request/RequestClient.ts @@ -214,9 +214,8 @@ export class RequestClient implements HttpClient { const headers = this.getHeaders(accessToken, 'application/json') if (this.fileUploadCsrfToken?.value) { - headers[ - this.fileUploadCsrfToken.headerName - ] = this.fileUploadCsrfToken.value + headers[this.fileUploadCsrfToken.headerName] = + this.fileUploadCsrfToken.value } try { @@ -333,9 +332,9 @@ export class RequestClient implements HttpClient { } private parseCsrfToken = (response: AxiosResponse): CsrfToken | undefined => { - const tokenHeader = (response.headers[ - 'x-csrf-header' - ] as string)?.toLowerCase() + const tokenHeader = ( + response.headers['x-csrf-header'] as string + )?.toLowerCase() if (tokenHeader) { const token = response.headers[tokenHeader] diff --git a/src/test/utils/isUrl.spec.ts b/src/test/utils/isUrl.spec.ts index 4ff92a9..928048c 100644 --- a/src/test/utils/isUrl.spec.ts +++ b/src/test/utils/isUrl.spec.ts @@ -28,12 +28,12 @@ describe('urlValidator', () => { it('should return false when the URL is null', () => { const url = null - expect(isUrl((url as unknown) as string)).toEqual(false) + expect(isUrl(url as unknown as string)).toEqual(false) }) it('should return false when the URL is undefined', () => { const url = undefined - expect(isUrl((url as unknown) as string)).toEqual(false) + expect(isUrl(url as unknown as string)).toEqual(false) }) }) From 98114c5591b329750a03147b2dd2427a957d2066 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 11 May 2021 08:23:40 +0100 Subject: [PATCH 03/10] fix(job-state-poll): Continue polling for job state despite errored requests --- src/SASViyaApiClient.ts | 42 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 8b526c2..87aded9 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -594,15 +594,16 @@ export class SASViyaApiClient { } } - const { result: createFolderResponse } = - await this.requestClient.post( - `/folders/folders?parentFolderUri=${parentFolderUri}`, - { - name: folderName, - type: 'folder' - }, - accessToken - ) + const { + result: createFolderResponse + } = await this.requestClient.post( + `/folders/folders?parentFolderUri=${parentFolderUri}`, + { + name: folderName, + type: 'folder' + }, + accessToken + ) // update folder map with newly created folder. await this.populateFolderMap( @@ -874,7 +875,9 @@ export class SASViyaApiClient { throw new Error(`URI of job definition was not found.`) } - const { result: jobDefinition } = await this.requestClient + const { + result: jobDefinition + } = await this.requestClient .get( `${this.serverUrl}${jobDefinitionLink.href}`, accessToken @@ -1107,7 +1110,11 @@ export class SASViyaApiClient { this.debug ) .catch((err) => { - throw prefixMessage(err, 'Error while getting job state. ') + console.error( + 'Error fetching job state. Starting poll, assuming job to be running.', + err + ) + return { result: 'running' } }) const currentState = state.trim() @@ -1134,10 +1141,17 @@ export class SASViyaApiClient { this.debug ) .catch((err) => { - throw prefixMessage( - err, - 'Error while getting job state after interval. ' + if (pollCount >= MAX_POLL_COUNT) { + throw prefixMessage( + err, + 'Error while getting job state after interval. ' + ) + } + console.error( + 'Error fetching job state. Resuming poll, assuming job to be running.', + err ) + return { result: 'running' } }) postedJobState = jobState.trim() From 15a774ff81109244be1eb209b0b1619b53d0f4fb Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 11 May 2021 08:29:15 +0100 Subject: [PATCH 04/10] chore(*): print URL when polling job state --- src/SASViyaApiClient.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 87aded9..95e5ef8 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -1101,6 +1101,9 @@ export class SASViyaApiClient { Promise.reject(`Job state link was not found.`) } + console.log( + `Attempting to poll job state from ${this.serverUrl}${stateLink.href}` + ) const { result: state } = await this.requestClient .get( `${this.serverUrl}${stateLink.href}?_action=wait&wait=300`, From ad8dbfd4ec92f73c64e24a71478742f82c18071e Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 11 May 2021 08:57:35 +0100 Subject: [PATCH 05/10] chore(*): add URL to logs --- src/SASViyaApiClient.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 95e5ef8..4e3b5ba 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -1101,9 +1101,6 @@ export class SASViyaApiClient { Promise.reject(`Job state link was not found.`) } - console.log( - `Attempting to poll job state from ${this.serverUrl}${stateLink.href}` - ) const { result: state } = await this.requestClient .get( `${this.serverUrl}${stateLink.href}?_action=wait&wait=300`, @@ -1114,7 +1111,7 @@ export class SASViyaApiClient { ) .catch((err) => { console.error( - 'Error fetching job state. Starting poll, assuming job to be running.', + `Error fetching job state from ${this.serverUrl}${stateLink.href}. Starting poll, assuming job to be running.`, err ) return { result: 'running' } @@ -1151,7 +1148,7 @@ export class SASViyaApiClient { ) } console.error( - 'Error fetching job state. Resuming poll, assuming job to be running.', + `Error fetching job state from ${this.serverUrl}${stateLink.href}. Resuming poll, assuming job to be running.`, err ) return { result: 'running' } From e03ec996d618860e98c65cd60bf5052677bf54f2 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 11 May 2021 09:25:17 +0100 Subject: [PATCH 06/10] chore(*): fix formatting --- src/SASViyaApiClient.ts | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 4e3b5ba..4f64e0d 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -594,16 +594,15 @@ export class SASViyaApiClient { } } - const { - result: createFolderResponse - } = await this.requestClient.post( - `/folders/folders?parentFolderUri=${parentFolderUri}`, - { - name: folderName, - type: 'folder' - }, - accessToken - ) + const { result: createFolderResponse } = + await this.requestClient.post( + `/folders/folders?parentFolderUri=${parentFolderUri}`, + { + name: folderName, + type: 'folder' + }, + accessToken + ) // update folder map with newly created folder. await this.populateFolderMap( @@ -875,9 +874,7 @@ export class SASViyaApiClient { throw new Error(`URI of job definition was not found.`) } - const { - result: jobDefinition - } = await this.requestClient + const { result: jobDefinition } = await this.requestClient .get( `${this.serverUrl}${jobDefinitionLink.href}`, accessToken From c1b200b0d8e74b820582ec0755251dbd08103622 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 11 May 2021 10:12:11 +0100 Subject: [PATCH 07/10] fix(job-state-poll): error out after max consecutive errors --- src/SASViyaApiClient.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 4f64e0d..6bcdf5b 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -1078,6 +1078,7 @@ export class SASViyaApiClient { ) { let POLL_INTERVAL = 300 let MAX_POLL_COUNT = 1000 + let MAX_ERROR_COUNT = 10 if (pollOptions) { POLL_INTERVAL = pollOptions.POLL_INTERVAL || POLL_INTERVAL @@ -1086,6 +1087,7 @@ export class SASViyaApiClient { let postedJobState = '' let pollCount = 0 + let errorCount = 0 const headers: any = { 'Content-Type': 'application/json', 'If-None-Match': etag @@ -1111,7 +1113,7 @@ export class SASViyaApiClient { `Error fetching job state from ${this.serverUrl}${stateLink.href}. Starting poll, assuming job to be running.`, err ) - return { result: 'running' } + return { result: 'unavailable' } }) const currentState = state.trim() @@ -1126,7 +1128,8 @@ export class SASViyaApiClient { if ( postedJobState === 'running' || postedJobState === '' || - postedJobState === 'pending' + postedJobState === 'pending' || + postedJobState === 'unavailable' ) { if (stateLink) { const { result: jobState } = await this.requestClient @@ -1138,7 +1141,10 @@ export class SASViyaApiClient { this.debug ) .catch((err) => { - if (pollCount >= MAX_POLL_COUNT) { + if ( + pollCount >= MAX_POLL_COUNT || + errorCount >= MAX_ERROR_COUNT + ) { throw prefixMessage( err, 'Error while getting job state after interval. ' @@ -1148,10 +1154,13 @@ export class SASViyaApiClient { `Error fetching job state from ${this.serverUrl}${stateLink.href}. Resuming poll, assuming job to be running.`, err ) - return { result: 'running' } + return { result: 'unavailable' } }) postedJobState = jobState.trim() + if (postedJobState != 'unavailable' && errorCount > 0) { + errorCount = 0 + } if (this.debug && printedState !== postedJobState) { console.log('Polling job status...') From 67ec27bab7734db5b1007bfb80c26bdeed3306d1 Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 11 May 2021 10:20:28 +0100 Subject: [PATCH 08/10] chore(*): increment error count --- src/SASViyaApiClient.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 6bcdf5b..9e85702 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -1141,6 +1141,7 @@ export class SASViyaApiClient { this.debug ) .catch((err) => { + errorCount++ if ( pollCount >= MAX_POLL_COUNT || errorCount >= MAX_ERROR_COUNT From 8f3a7f33f82a85251bef02717de486f66848bbad Mon Sep 17 00:00:00 2001 From: Krishna Acondy Date: Tue, 11 May 2021 10:23:47 +0100 Subject: [PATCH 09/10] chore(*): reduce max error count --- src/SASViyaApiClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index 9e85702..72e9fa6 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -1078,7 +1078,7 @@ export class SASViyaApiClient { ) { let POLL_INTERVAL = 300 let MAX_POLL_COUNT = 1000 - let MAX_ERROR_COUNT = 10 + let MAX_ERROR_COUNT = 5 if (pollOptions) { POLL_INTERVAL = pollOptions.POLL_INTERVAL || POLL_INTERVAL From 53a7b1c9e60df68a2ad77554d540e37c28d99df2 Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Thu, 13 May 2021 17:29:48 +0300 Subject: [PATCH 10/10] fix(request): returned response with log --- src/job-execution/JesJobExecutor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/job-execution/JesJobExecutor.ts b/src/job-execution/JesJobExecutor.ts index 60cf52f..42d22a4 100644 --- a/src/job-execution/JesJobExecutor.ts +++ b/src/job-execution/JesJobExecutor.ts @@ -33,7 +33,7 @@ export class JesJobExecutor extends BaseJobExecutor { .then((response) => { this.appendRequest(response, sasJob, config.debug) - resolve(response.result) + resolve(response) }) .catch(async (e: Error) => { if (e instanceof JobExecutionError) {