From 81be11f3b9e049127db64a3742f42ed80d9010c8 Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Tue, 15 Sep 2020 12:48:33 +0300 Subject: [PATCH] refactor(error): refactoring errors and fixing spelling --- src/FileUploader.ts | 5 ++- src/SASViyaApiClient.ts | 87 +++++++++++++++++++------------------ src/SASjs.ts | 96 +++++++++++++++++++---------------------- src/SessionManager.ts | 6 +-- 4 files changed, 96 insertions(+), 98 deletions(-) diff --git a/src/FileUploader.ts b/src/FileUploader.ts index c7be45a..2dc5ac5 100644 --- a/src/FileUploader.ts +++ b/src/FileUploader.ts @@ -18,7 +18,8 @@ export class FileUploader { private retryCount = 0 public uploadFile(sasJob: string, files: UploadFile[], params: any) { - if (files?.length < 1) throw new Error('Atleast one file must be provided') + if (files?.length < 1) + throw new Error('At least one file must be provided.') let paramsString = '' @@ -75,7 +76,7 @@ export class FileUploader { }) .then((responseText) => { if (isLogInRequired(responseText)) - reject('You must be logged in to upload a fle') + reject('You must be logged in to upload a file') // FIXME: use ErrorResponse if (needsRetry(responseText)) { if (this.retryCount < requestRetryLimit) { diff --git a/src/SASViyaApiClient.ts b/src/SASViyaApiClient.ts index b05e207..19c076f 100644 --- a/src/SASViyaApiClient.ts +++ b/src/SASViyaApiClient.ts @@ -21,7 +21,7 @@ import { formatDataForRequest } from './utils/formatDataForRequest' import { SessionManager } from './SessionManager' /** - * A client for interfacing with the SAS Viya REST API + * A client for interfacing with the SAS Viya REST API. * */ export class SASViyaApiClient { @@ -61,7 +61,7 @@ export class SASViyaApiClient { } /** - * returns an object containing the Server URL and root folder name + * Returns an object containing the server URL and root folder name. */ public getConfig() { return { @@ -71,9 +71,9 @@ export class SASViyaApiClient { } /** - * Updates server URL or root folder name when not null + * Updates server URL and root folder name, if it was not set. * @param serverUrl - the URL of the server. - * @param rootFolderName - the name for rootFolderName. + * @param rootFolderName - the name for root folder. */ public setConfig(serverUrl: string, rootFolderName: string) { if (serverUrl) this.serverUrl = serverUrl @@ -222,7 +222,7 @@ export class SASViyaApiClient { * Creates a compute context on the given server. * @param contextName - the name of the context to be created. * @param launchContextName - the name of the launcher context used by the compute service. - * @param sharedAccountId - the ID of the account to run the servers for this context as. + * @param sharedAccountId - the ID of the account to run the servers for this context. * @param autoExecLines - the lines of code to execute during session initialization. * @param authorizedUsers - an optional list of authorized user IDs. * @param accessToken - an access token for an authorized user. @@ -236,15 +236,15 @@ export class SASViyaApiClient { accessToken?: string ) { if (!contextName) { - throw new Error('Missing context name.') + throw new Error('Context name is required.') } if (!launchContextName) { - throw new Error('Missing launch context name.') + throw new Error('Launch context name is required.') } if (!sharedAccountId) { - throw new Error('Missing shared account ID.') + throw new Error('Shared account ID is required.') } const headers: any = { @@ -328,11 +328,11 @@ export class SASViyaApiClient { if (e && e.status === 404) { throw new Error( - `The context ${contextName} was not found on this server.` + `The context '${contextName}' was not found on this server.` ) } throw new Error( - `An error occurred when fetching the context ${contextName}` + `An error occurred when fetching the context '${contextName}'.` ) }) @@ -364,7 +364,7 @@ export class SASViyaApiClient { */ public async deleteContext(contextName: string, accessToken?: string) { if (!contextName) { - throw new Error('Invalid context Name.') + throw new Error('Invalid context name.') } const headers: any = { @@ -391,13 +391,13 @@ export class SASViyaApiClient { /** * Executes code on the current SAS Viya server. * @param fileName - a name for the file being submitted for execution. - * @param linesOfCode - an array of lines of code to execute. + * @param linesOfCode - an array of code lines to execute. * @param contextName - the context to execute the code in. * @param accessToken - an access token for an authorized user. * @param sessionId - optional session ID to reuse. - * @param silent - optional flag to turn of logging. + * @param silent - optional flag to disable logging. * @param data - execution data. - * @param debug - flag taht indicates debug mode. + * @param debug - flag that indicates debug mode. * @param expectWebout - flag that indicates that web output is expected */ public async executeScript( @@ -486,11 +486,11 @@ export class SASViyaApiClient { ) if (!silent) { - console.log(`Job has been submitted for ${fileName}`) + console.log(`Job has been submitted for '${fileName}'.`) console.log( - `You can monitor the job progress at ${this.serverUrl}${ + `You can monitor the job progress at '${this.serverUrl}${ postedJob.links.find((l: any) => l.rel === 'state')!.href - }` + }'.` ) } @@ -581,7 +581,7 @@ export class SASViyaApiClient { isForced?: boolean ): Promise { if (!parentFolderPath && !parentFolderUri) { - throw new Error('Parent folder path or uri is required') + throw new Error('Path or URI of the parent folder is required.') } if (!parentFolderUri && parentFolderPath) { @@ -589,7 +589,9 @@ export class SASViyaApiClient { if (!parentFolderUri) { if (isForced) this.isForceDeploy = true - console.log(`Parent folder is not present: ${parentFolderPath}`) + console.log( + `Parent folder at path '${parentFolderPath}' is not present.` + ) const newParentFolderPath = parentFolderPath.substring( 0, @@ -597,10 +599,10 @@ export class SASViyaApiClient { ) const newFolderName = `${parentFolderPath.split('/').pop()}` if (newParentFolderPath === '') { - throw new Error('Root Folder should have been present on server') + throw new Error('Root folder has to be present on the server.') } console.log( - `Creating Parent Folder:\n${newFolderName} in ${newParentFolderPath}` + `Creating parent folder:\n'${newFolderName}' in '${newParentFolderPath}'` ) const parentFolder = await this.createFolder( newFolderName, @@ -608,7 +610,9 @@ export class SASViyaApiClient { undefined, accessToken ) - console.log(`Parent Folder "${newFolderName}" successfully created.`) + console.log( + `Parent folder '${newFolderName}' has been successfully created.` + ) parentFolderUri = `/folders/folders/${parentFolder.id}` } else if (isForced && accessToken && !this.isForceDeploy) { this.isForceDeploy = true @@ -622,11 +626,11 @@ export class SASViyaApiClient { const newFolderName = `${parentFolderPath.split('/').pop()}` if (newParentFolderPath === '') { - throw new Error('Root Folder should have been present on server') + throw new Error(`Root folder has to be present on the server.`) } console.log( - `Creating Parent Folder:\n${newFolderName} in ${newParentFolderPath}` + `Creating parent folder:\n'${newFolderName}' in '${newParentFolderPath}'` ) const parentFolder = await this.createFolder( @@ -636,7 +640,9 @@ export class SASViyaApiClient { accessToken ) - console.log(`Parent Folder "${newFolderName}" successfully created.`) + console.log( + `Parent folder '${newFolderName}' has been successfully created.` + ) parentFolderUri = `/folders/folders/${parentFolder.id}` } @@ -681,9 +687,7 @@ export class SASViyaApiClient { accessToken?: string ) { if (!parentFolderPath && !parentFolderUri) { - throw new Error( - 'Either parentFolderPath or parentFolderUri must be provided' - ) + throw new Error(`Path to or URI of the parent folder is required.`) } if (!parentFolderUri && parentFolderPath) { @@ -896,16 +900,14 @@ export class SASViyaApiClient { await this.populateRootFolder(accessToken) } if (!this.rootFolder) { - console.error('Root folder was not found') - throw new Error('Root folder was not found') + throw new Error(`Root folder was not found.`) } if (!this.rootFolderMap.size) { await this.populateRootFolderMap(accessToken) } if (!this.rootFolderMap.size) { - console.error(`The job ${sasJob} was not found in ${this.rootFolderName}`) throw new Error( - `The job ${sasJob} was not found in ${this.rootFolderName}` + `The job '${sasJob}' was not found in '${this.rootFolderName}'.` ) } @@ -920,7 +922,7 @@ export class SASViyaApiClient { const jobToExecute = jobFolder?.find((item) => item.name === jobName) if (!jobToExecute) { - throw new Error('Job was not found.') + throw new Error(`Job was not found.`) } let code = jobToExecute?.code @@ -931,8 +933,7 @@ export class SASViyaApiClient { ) if (!jobDefinitionLink) { - console.error('Job definition URI was not found.') - throw new Error('Job definition URI was not found.') + throw new Error(`URI of job definition was not found.`) } const { result: jobDefinition } = await this.request( @@ -979,14 +980,14 @@ export class SASViyaApiClient { } if (!this.rootFolder) { - throw new Error('Root folder was not found') + throw new Error(`Root folder was not found.`) } if (!this.rootFolderMap.size) { await this.populateRootFolderMap(accessToken) } if (!this.rootFolderMap.size) { throw new Error( - `The job ${sasJob} was not found in ${this.rootFolderName}` + `The job '${sasJob}' was not found in folder '${this.rootFolderName}'.` ) } @@ -1095,7 +1096,7 @@ export class SASViyaApiClient { return { result: jobResult?.result, log } } else { throw new Error( - `The job ${sasJob} was not found at the location ${this.rootFolderName}` + `The job '${sasJob}' was not found in folder '${this.rootFolderName}'.` ) } } @@ -1114,7 +1115,9 @@ export class SASViyaApiClient { requestInfo ) if (!folder) { - throw new Error('Cannot populate RootFolderMap unless rootFolder exists') + throw new Error( + `Not able to populate root folder map, because folder '${this.rootFolderName}' does not exist.` + ) } const { result: members } = await this.request<{ items: any[] }>( `${this.serverUrl}/folders/folders/${folder.id}/members`, @@ -1192,7 +1195,7 @@ export class SASViyaApiClient { } const stateLink = postedJob.links.find((l: any) => l.rel === 'state') if (!stateLink) { - Promise.reject('Job state link was not found.') + Promise.reject(`Job state link was not found.`) } const { result: state } = await this.request( @@ -1380,13 +1383,13 @@ export class SASViyaApiClient { console.error(e) throw new Error( - `An error occurred when fetching the context with ID ${contextName}` + `An error occurred when fetching the context '${contextName}'.` ) }) if (!contexts || !(contexts.items && contexts.items.length)) { throw new Error( - `The context ${contextName} was not found on ${this.serverUrl}.` + `The context '${contextName}' was not found at '${this.serverUrl}'.` ) } diff --git a/src/SASjs.ts b/src/SASjs.ts index 1818dec..e1ac176 100644 --- a/src/SASjs.ts +++ b/src/SASjs.ts @@ -84,9 +84,8 @@ export default class SASjs { serverName: string, repositoryName: string ) { - if (this.sasjsConfig.serverType !== ServerType.SAS9) { - throw new Error('This operation is only supported on SAS9 servers.') - } + this.isMethodSupported('executeScriptSAS9', ServerType.SAS9) + return await this.sas9ApiClient?.executeScript( linesOfCode, serverName, @@ -95,16 +94,14 @@ export default class SASjs { } public async getAllContexts(accessToken: string) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('getAllContexts', ServerType.SASViya) + return await this.sasViyaApiClient!.getAllContexts(accessToken) } public async getExecutableContexts(accessToken: string) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('getExecutableContexts', ServerType.SASViya) + return await this.sasViyaApiClient!.getExecutableContexts(accessToken) } @@ -125,9 +122,8 @@ export default class SASjs { authorizedUsers: string[], accessToken: string ) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('createContext', ServerType.SASViya) + return await this.sasViyaApiClient!.createContext( contextName, launchContextName, @@ -149,9 +145,8 @@ export default class SASjs { editedContext: EditContextInput, accessToken?: string ) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('editContext', ServerType.SASViya) + return await this.sasViyaApiClient!.editContext( contextName, editedContext, @@ -165,16 +160,14 @@ export default class SASjs { * @param accessToken - an access token for an authorized user. */ public async deleteContext(contextName: string, accessToken?: string) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('deleteContext', ServerType.SASViya) + return await this.sasViyaApiClient!.deleteContext(contextName, accessToken) } public async createSession(contextName: string, accessToken: string) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('createSession', ServerType.SASViya) + return await this.sasViyaApiClient!.createSession(contextName, accessToken) } @@ -186,9 +179,8 @@ export default class SASjs { sessionId = '', silent = false ) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('executeScriptSASViya', ServerType.SASViya) + return await this.sasViyaApiClient!.executeScript( fileName, linesOfCode, @@ -217,9 +209,8 @@ export default class SASjs { sasApiClient?: SASViyaApiClient, isForced?: boolean ) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('createFolder', ServerType.SASViya) + if (sasApiClient) return await sasApiClient.createFolder( folderName, @@ -244,9 +235,8 @@ export default class SASjs { accessToken?: string, sasApiClient?: SASViyaApiClient ) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('createJobDefinition', ServerType.SASViya) + if (sasApiClient) return await sasApiClient!.createJobDefinition( jobName, @@ -265,9 +255,8 @@ export default class SASjs { } public async getAuthCode(clientId: string) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('getAuthCode', ServerType.SASViya) + return await this.sasViyaApiClient!.getAuthCode(clientId) } @@ -276,9 +265,8 @@ export default class SASjs { clientSecret: string, authCode: string ) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('getAccessToken', ServerType.SASViya) + return await this.sasViyaApiClient!.getAccessToken( clientId, clientSecret, @@ -291,9 +279,8 @@ export default class SASjs { clientSecret: string, refreshToken: string ) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('refreshTokens', ServerType.SASViya) + return await this.sasViyaApiClient!.refreshTokens( clientId, clientSecret, @@ -302,9 +289,8 @@ export default class SASjs { } public async deleteClient(clientId: string, accessToken: string) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('deleteClient', ServerType.SASViya) + return await this.sasViyaApiClient!.deleteClient(clientId, accessToken) } @@ -570,9 +556,7 @@ export default class SASjs { accessToken?: string, isForced = false ) { - if (this.sasjsConfig.serverType !== ServerType.SASViya) { - throw new Error('This operation is only supported on SAS Viya servers.') - } + this.isMethodSupported('deployServicePack', ServerType.SASViya) let sasApiClient: any = null if (serverUrl || appLoc) { @@ -686,7 +670,7 @@ export default class SASjs { resolve(retryResponse) } else { this.retryCountComputeApi = 0 - reject({ MESSAGE: 'Compute API retry requests limit reached' }) + reject({ MESSAGE: 'Compute API retry requests limit reached.' }) // FIXME: use ErrorResponse } } @@ -697,7 +681,7 @@ export default class SASjs { sasjsWaitingRequest.config = config this.sasjsWaitingRequests.push(sasjsWaitingRequest) } else { - reject({ MESSAGE: error || 'Job execution failed' }) + reject({ MESSAGE: error || 'Job execution failed.' }) // FIXME: use ErrorResponse } this.appendSasjsRequest(response.log, sasJob, null) @@ -779,11 +763,11 @@ export default class SASjs { resolve(retryResponse) } else { this.retryCountJeseApi = 0 - reject({ MESSAGE: 'Jes API retry requests limit reached' }) + reject({ MESSAGE: 'JES API retry requests limit reached' }) // FIXME: use ErrorResponse } } - reject({ MESSAGE: (e && e.message) || 'Job execution failed' }) + reject({ MESSAGE: (e && e.message) || 'Job execution failed.' }) // FIXME: use ErrorResponse }) ) } @@ -1074,7 +1058,7 @@ export default class SASjs { resolve(resText) }) } else { - reject('No debug info in response') + reject('No debug info found in response.') // FIXME: use ErrorResponse } }) } @@ -1353,7 +1337,7 @@ export default class SASjs { ) break default: - throw new Error(`Unidenitied member present in Json: ${member.name}`) + throw new Error(`Unidentified member '${member.name}' provided.`) } if (member.type === 'folder' && member.members && member.members.length) await this.createFoldersAndServices( @@ -1365,4 +1349,14 @@ export default class SASjs { ) }) } + + private isMethodSupported(method: string, serverType: string) { + if (this.sasjsConfig.serverType !== serverType) { + throw new Error( + `Method '${method}' is only supported on ${ + serverType === ServerType.SAS9 ? 'SAS9' : 'SAS Viya' + } servers.` + ) + } + } } diff --git a/src/SessionManager.ts b/src/SessionManager.ts index fc3eb56..f439f07 100644 --- a/src/SessionManager.ts +++ b/src/SessionManager.ts @@ -93,7 +93,7 @@ export class SessionManager { if (!currentContext) { throw new Error( - `The context ${this.contextName} was not found on the server ${this.serverUrl}` + `The context '${this.contextName}' was not found on the server ${this.serverUrl}.` ) } @@ -128,7 +128,7 @@ export class SessionManager { if (sessionState === 'pending') { if (stateLink) { if (!silent) { - console.log('Polling session status... \n') + console.log('Polling session status... \n') // ? } const { result: state } = await this.request( `${this.serverUrl}${stateLink.href}?wait=30`, @@ -140,7 +140,7 @@ export class SessionManager { sessionState = state.trim() if (!silent) { - console.log(`Current state: ${sessionState}\n`) + console.log(`Current state is '${sessionState}'\n`) } resolve(sessionState) }