diff --git a/src/FileUploader.ts b/src/FileUploader.ts index 4e117df..38d2f52 100644 --- a/src/FileUploader.ts +++ b/src/FileUploader.ts @@ -75,9 +75,7 @@ export class FileUploader { this.requestClient, this.sasjsConfig.serverUrl ) - return typeof jsonResponse === 'string' - ? getValidJson(jsonResponse) - : jsonResponse + return jsonResponse } return typeof res.result === 'string' diff --git a/src/job-execution/WebJobExecutor.ts b/src/job-execution/WebJobExecutor.ts index c75a06e..560b1bf 100644 --- a/src/job-execution/WebJobExecutor.ts +++ b/src/job-execution/WebJobExecutor.ts @@ -2,7 +2,8 @@ import { ServerType } from '@sasjs/utils/types' import { ErrorResponse, JobExecutionError, - LoginRequiredError + LoginRequiredError, + WeboutResponseError } from '../types/errors' import { generateFileUploadForm } from '../file/generateFileUploadForm' import { generateTableUploadForm } from '../file/generateTableUploadForm' @@ -102,10 +103,10 @@ export class WebJobExecutor extends BaseJobExecutor { const requestPromise = new Promise((resolve, reject) => { this.requestClient!.post(apiUrl, formData, undefined) - .then(async (res) => { + .then(async (res: any) => { if (this.serverType === ServerType.SasViya && config.debug) { const jsonResponse = await parseSasViyaDebugResponse( - res.result as string, + res.result, this.requestClient, this.serverUrl ) @@ -113,18 +114,15 @@ export class WebJobExecutor extends BaseJobExecutor { resolve(jsonResponse) } if (this.serverType === ServerType.Sas9 && config.debug) { - const jsonResponse = parseWeboutResponse(res.result as string) - if (jsonResponse === '') { - throw new Error( - 'Valid JSON could not be extracted from response.' - ) - } + let jsonResponse = res.result + if (typeof res.result === 'string') + jsonResponse = parseWeboutResponse(res.result, apiUrl) getValidJson(jsonResponse) this.appendRequest(res, sasJob, config.debug) resolve(res.result) } - getValidJson(res.result as string) + getValidJson(res.result) this.appendRequest(res, sasJob, config.debug) resolve(res.result) }) diff --git a/src/request/RequestClient.ts b/src/request/RequestClient.ts index e44a8c4..28c5512 100644 --- a/src/request/RequestClient.ts +++ b/src/request/RequestClient.ts @@ -429,13 +429,7 @@ export class RequestClient implements HttpClient { } } catch { try { - const weboutResponse = parseWeboutResponse(response.data) - if (weboutResponse === '') { - throw new Error('Valid JSON could not be extracted from response.') - } - - const jsonResponse = getValidJson(weboutResponse) - parsedResponse = jsonResponse + parsedResponse = JSON.parse(parseWeboutResponse(response.data)) } catch { parsedResponse = response.data } diff --git a/src/test/utils/getValidJson.spec.ts b/src/test/utils/getValidJson.spec.ts index e7fbf66..a84eb04 100644 --- a/src/test/utils/getValidJson.spec.ts +++ b/src/test/utils/getValidJson.spec.ts @@ -1,4 +1,5 @@ import { getValidJson } from '../../utils' +import { JsonParseArrayError, InvalidJsonError } from '../../types/errors' describe('jsonValidator', () => { it('should not throw an error with a valid json', () => { @@ -19,23 +20,17 @@ describe('jsonValidator', () => { it('should throw an error with an invalid json', () => { const json = `{\"test\":\"test\"\"test2\":\"test\"}` - let errorThrown = false - try { + const test = () => { getValidJson(json) - } catch (error) { - errorThrown = true } - expect(errorThrown).toBe(true) + expect(test).toThrowError(InvalidJsonError) }) it('should throw an error when an array is passed', () => { const array = ['hello', 'world'] - let errorThrown = false - try { + const test = () => { getValidJson(array) - } catch (error) { - errorThrown = true } - expect(errorThrown).toBe(true) + expect(test).toThrow(JsonParseArrayError) }) }) diff --git a/src/types/errors/InvalidJsonError.ts b/src/types/errors/InvalidJsonError.ts new file mode 100644 index 0000000..f59339a --- /dev/null +++ b/src/types/errors/InvalidJsonError.ts @@ -0,0 +1,7 @@ +export class InvalidJsonError extends Error { + constructor() { + super('Error: invalid Json string') + this.name = 'InvalidJsonError' + Object.setPrototypeOf(this, InvalidJsonError.prototype) + } +} diff --git a/src/types/errors/JsonParseArrayError.ts b/src/types/errors/JsonParseArrayError.ts new file mode 100644 index 0000000..ad08ecd --- /dev/null +++ b/src/types/errors/JsonParseArrayError.ts @@ -0,0 +1,7 @@ +export class JsonParseArrayError extends Error { + constructor() { + super('Can not parse array object to json.') + this.name = 'JsonParseArrayError' + Object.setPrototypeOf(this, JsonParseArrayError.prototype) + } +} diff --git a/src/types/errors/WeboutResponseError.ts b/src/types/errors/WeboutResponseError.ts new file mode 100644 index 0000000..9ca1e80 --- /dev/null +++ b/src/types/errors/WeboutResponseError.ts @@ -0,0 +1,7 @@ +export class WeboutResponseError extends Error { + constructor(public url: string) { + super(`Error: error while parsing response from ${url}`) + this.name = 'WeboutResponseError' + Object.setPrototypeOf(this, WeboutResponseError.prototype) + } +} diff --git a/src/types/errors/index.ts b/src/types/errors/index.ts index cca1a97..e2b0766 100644 --- a/src/types/errors/index.ts +++ b/src/types/errors/index.ts @@ -8,3 +8,6 @@ export * from './NotFoundError' export * from './ErrorResponse' export * from './NoSessionStateError' export * from './RootFolderNotFoundError' +export * from './JsonParseArrayError' +export * from './WeboutResponseError' +export * from './InvalidJsonError' diff --git a/src/utils/getValidJson.ts b/src/utils/getValidJson.ts index 0313157..17f9cbb 100644 --- a/src/utils/getValidJson.ts +++ b/src/utils/getValidJson.ts @@ -1,16 +1,18 @@ +import { JsonParseArrayError, InvalidJsonError } from '../types/errors' + /** * if string passed then parse the string to json else if throw error for all other types unless it is not a valid json object. * @param str - string to check. */ export const getValidJson = (str: string | object) => { try { - if (Array.isArray(str)) { - throw new Error('Can not parse array object to json.') - } + if (Array.isArray(str)) throw new JsonParseArrayError() + if (typeof str === 'object') return str return JSON.parse(str) } catch (e) { - throw new Error('Invalid JSON response.') + if (e instanceof JsonParseArrayError) throw e + throw new InvalidJsonError() } } diff --git a/src/utils/parseViyaDebugResponse.ts b/src/utils/parseViyaDebugResponse.ts index 3137995..b0227f2 100644 --- a/src/utils/parseViyaDebugResponse.ts +++ b/src/utils/parseViyaDebugResponse.ts @@ -1,4 +1,5 @@ import { RequestClient } from '../request/RequestClient' +import { getValidJson } from '../utils' /** * When querying a Viya job using the Web approach (as opposed to using the APIs) with _DEBUG enabled, @@ -25,5 +26,5 @@ export const parseSasViyaDebugResponse = async ( return requestClient .get(serverUrl + jsonUrl, undefined) - .then((res) => res.result) + .then((res: any) => getValidJson(res.result)) } diff --git a/src/utils/parseWeboutResponse.ts b/src/utils/parseWeboutResponse.ts index f9bc4db..30d91b6 100644 --- a/src/utils/parseWeboutResponse.ts +++ b/src/utils/parseWeboutResponse.ts @@ -1,4 +1,6 @@ -export const parseWeboutResponse = (response: string) => { +import { WeboutResponseError } from '../types/errors' + +export const parseWeboutResponse = (response: string, url?: string) => { let sasResponse = '' if (response.includes('>>weboutBEGIN<<')) { @@ -7,6 +9,7 @@ export const parseWeboutResponse = (response: string) => { .split('>>weboutBEGIN<<')[1] .split('>>weboutEND<<')[0] } catch (e) { + if (url) throw new WeboutResponseError(url) sasResponse = '' console.error(e) }