diff --git a/src/App.svelte b/src/App.svelte index cfdbbe2..3b2356b 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -51,7 +51,7 @@ import { createDebouncedMethod } from "./utility/misc-utils.js"; import { decryptText, encryptText } from "./utility/crypto-utils.js"; import { performUserLogout } from "./lib/session.js"; - import { handleErrorIfAny } from "./lib/error-handling.js"; + import { handleAnyError } from "./lib/error-handling.js"; let topAppBar: TopAppBarComponentDev; @@ -64,10 +64,13 @@ const loadBucketList = createDebouncedMethod(async () => { incrementActiveGlobalObtrusiveTaskCount(); - let response = await callBucketListApi({}); - if (await handleErrorIfAny(response)) return; - bucketList.set(response.bucketList); - decrementActiveGlobalObtrusiveTaskCount(); + try { + let response = await callBucketListApi({}); + bucketList.set(response.bucketList); + decrementActiveGlobalObtrusiveTaskCount(); + } catch (ex) { + return await handleAnyError(ex); + } }, 100); const logoutClicked = async () => { diff --git a/src/component/page/CreateBucketPage.svelte b/src/component/page/CreateBucketPage.svelte index a8015a4..8e4b8a5 100644 --- a/src/component/page/CreateBucketPage.svelte +++ b/src/component/page/CreateBucketPage.svelte @@ -28,7 +28,7 @@ import { encryptText } from "../../utility/crypto-utils.js"; import { BUCKET_CRYPTO_SPEC } from "../../constant/crypto-specs.js"; import { bucketList } from "../../store/content.js"; - import { handleErrorIfAny } from "../../lib/error-handling.js"; + import { handleAnyError } from "../../lib/error-handling.js"; const NEW_BUCKET_ID = "new"; @@ -41,31 +41,36 @@ const finalForm = form(name, encryptionPassword); const saveClicked = async () => { - let bucketPassword = $encryptionPassword.value; + try { + let bucketPassword = $encryptionPassword.value; - incrementActiveGlobalObtrusiveTaskCount(); + incrementActiveGlobalObtrusiveTaskCount(); - let cryptDataObject = await encryptText(BUCKET_CRYPTO_SPEC, bucketPassword); + let cryptDataObject = await encryptText( + BUCKET_CRYPTO_SPEC, + bucketPassword + ); - let cryptData = JSON.stringify(cryptDataObject); + let cryptData = JSON.stringify(cryptDataObject); - let response = await callBucketCreateApi({ - name: $name.value, - cryptSpec: BUCKET_CRYPTO_SPEC, - cryptData, - metaData: { - createFrom: "nkrypt.xyz app", - }, - }); - if (await handleErrorIfAny(response)) return; + let response = await callBucketCreateApi({ + name: $name.value, + cryptSpec: BUCKET_CRYPTO_SPEC, + cryptData, + metaData: { + createFrom: "nkrypt.xyz app", + }, + }); - let response2 = await callBucketListApi({}); - if (await handleErrorIfAny(response)) return; + let response2 = await callBucketListApi({}); - bucketList.set(response2.bucketList); + bucketList.set(response2.bucketList); - replace("/dashboard"); - decrementActiveGlobalObtrusiveTaskCount(); + replace("/dashboard"); + decrementActiveGlobalObtrusiveTaskCount(); + } catch (ex) { + return await handleAnyError(ex); + } }; diff --git a/src/component/page/ExplorePage.svelte b/src/component/page/ExplorePage.svelte index 5dab174..e9efadf 100644 --- a/src/component/page/ExplorePage.svelte +++ b/src/component/page/ExplorePage.svelte @@ -16,7 +16,7 @@ callDirectoryCreateApi, callDirectoryGetApi, } from "../../integration/content-apis.js"; - import { handleErrorIfAny } from "../../lib/error-handling.js"; + import { handleAnyError } from "../../lib/error-handling.js"; import { getPasswordForBucket, setPasswordForBucket, @@ -76,14 +76,17 @@ }; const getDirectory = async (directoryId: string) => { - incrementActiveGlobalObtrusiveTaskCount(); - let response = await callDirectoryGetApi({ - bucketId: currentBucket._id, - directoryId: directoryId, - }); - if (await handleErrorIfAny(response)) return; - decrementActiveGlobalObtrusiveTaskCount(); - return response; + try { + incrementActiveGlobalObtrusiveTaskCount(); + let response = await callDirectoryGetApi({ + bucketId: currentBucket._id, + directoryId: directoryId, + }); + decrementActiveGlobalObtrusiveTaskCount(); + return response; + } catch (ex) { + return await handleAnyError(ex); + } }; const loadRootDirectory = async (): Promise => { @@ -160,21 +163,24 @@ }); const createDirectoryClicked = async () => { - let name = await showPrompt("Create directory", "Enter directory name"); - if (!name) return; - - incrementActiveGlobalObtrusiveTaskCount(); - let response = await callDirectoryCreateApi({ - bucketId: currentBucket._id, - name, - parentDirectoryId: (currentDirectory as any)._id, - metaData: {}, - encryptedMetaData: await encryptObject({}, currentBucketPassword), - }); - if (await handleErrorIfAny(response)) return; - decrementActiveGlobalObtrusiveTaskCount(); + try { + let name = await showPrompt("Create directory", "Enter directory name"); + if (!name) return; + + incrementActiveGlobalObtrusiveTaskCount(); + let response = await callDirectoryCreateApi({ + bucketId: currentBucket._id, + name, + parentDirectoryId: (currentDirectory as any)._id, + metaData: {}, + encryptedMetaData: await encryptObject({}, currentBucketPassword), + }); + decrementActiveGlobalObtrusiveTaskCount(); - explorePath(currentPath); + explorePath(currentPath); + } catch (ex) { + return await handleAnyError(ex); + } }; const childDirectoryClicked = async (childDirectory) => { diff --git a/src/component/page/ExplorePage/FileOperationModal.svelte b/src/component/page/ExplorePage/FileOperationModal.svelte index e8755d4..0058937 100644 --- a/src/component/page/ExplorePage/FileOperationModal.svelte +++ b/src/component/page/ExplorePage/FileOperationModal.svelte @@ -34,13 +34,12 @@ import Button, { Label } from "@smui/button"; import CircularProgress from "@smui/circular-progress"; import { expressBytesPrettified } from "../../../utility/value-utils.js"; - import { CodedError, handleErrorIfAny } from "../../../lib/error-handling.js"; import { downloadAndDecryptFile, encryptAndUploadFile, } from "../../../lib/crypto-transit.js"; import LinearProgress from "@smui/linear-progress"; - import { clientError } from "../../../constant/client-errors.js"; + import { clientErrorDef } from "../../../constant/client-errors.js"; const FileOperationModalState = { IDLE: "IDLE", diff --git a/src/component/page/ExplorePage/FileUploadModal.svelte b/src/component/page/ExplorePage/FileUploadModal.svelte index 6b09967..162c3cb 100644 --- a/src/component/page/ExplorePage/FileUploadModal.svelte +++ b/src/component/page/ExplorePage/FileUploadModal.svelte @@ -32,7 +32,7 @@ import Button, { Label } from "@smui/button"; import CircularProgress from "@smui/circular-progress"; import { expressBytesPrettified } from "../../../utility/value-utils.js"; - import { handleErrorIfAny } from "../../../lib/error-handling.js"; + import { handleAnyError } from "../../../lib/error-handling.js"; import { encryptAndUploadFile } from "../../../lib/crypto-transit.js"; import LinearProgress from "@smui/linear-progress"; @@ -156,51 +156,53 @@ }; const startUploadClicked = async () => { - let fileId = null; - let { bucketId, _id: parentDirectoryId } = directory; - - if (requiresOverwrite) { - let matchingFile = childFileList.find((file) => file.name === fileName); - fileId = matchingFile._id; - } else { - incrementActiveGlobalObtrusiveTaskCount(); - let response = await callFileCreateApi({ + try { + let fileId = null; + let { bucketId, _id: parentDirectoryId } = directory; + + if (requiresOverwrite) { + let matchingFile = childFileList.find((file) => file.name === fileName); + fileId = matchingFile._id; + } else { + incrementActiveGlobalObtrusiveTaskCount(); + let response = await callFileCreateApi({ + bucketId, + name: fileName, + parentDirectoryId, + metaData: {}, + encryptedMetaData: await encryptObject({}, bucketPassword), + }); + if (response.hasError) { + setAnswer(null); + return; + } + decrementActiveGlobalObtrusiveTaskCount(); + ({ fileId } = response); + } + + state = FileUploadModalState.FILE_UPLOAD; + uploadProgress = { + totalBytes: 0, + encryptedBytes: 0, + }; + let response = await encryptAndUploadFile( bucketId, - name: fileName, - parentDirectoryId, - metaData: {}, - encryptedMetaData: await encryptObject({}, bucketPassword), - }); + fileId, + uploadCandidate, + bucketPassword, + updateProgressFn, + selectedUploadMethod + ); if (response.hasError) { setAnswer(null); - await handleErrorIfAny(response); return; } - decrementActiveGlobalObtrusiveTaskCount(); - ({ fileId } = response); - } - state = FileUploadModalState.FILE_UPLOAD; - uploadProgress = { - totalBytes: 0, - encryptedBytes: 0, - }; - let response = await encryptAndUploadFile( - bucketId, - fileId, - uploadCandidate, - bucketPassword, - updateProgressFn, - selectedUploadMethod - ); - if (response.hasError) { - setAnswer(null); - await handleErrorIfAny(response); + setAnswer(response); return; + } catch (ex) { + return await handleAnyError(ex); } - - setAnswer(response); - return; }; let shouldShowDialog = false; diff --git a/src/component/page/LoginPage.svelte b/src/component/page/LoginPage.svelte index 1858424..a59d9b1 100644 --- a/src/component/page/LoginPage.svelte +++ b/src/component/page/LoginPage.svelte @@ -23,24 +23,27 @@ decrementActiveGlobalObtrusiveTaskCount, incrementActiveGlobalObtrusiveTaskCount, } from "../../store/ui.js"; - import { handleErrorIfAny } from "../../lib/error-handling.js"; + import { handleAnyError } from "../../lib/error-handling.js"; const loginClicked = async () => { - let payload = extract($finalForm.summary, ["userName", "password"]); - incrementActiveGlobalObtrusiveTaskCount(); - let response = await callUserLoginApi($server.value, payload); - if (await handleErrorIfAny(response)) return; - decrementActiveGlobalObtrusiveTaskCount(); + try { + let payload = extract($finalForm.summary, ["userName", "password"]); + incrementActiveGlobalObtrusiveTaskCount(); + let response = await callUserLoginApi($server.value, payload); + decrementActiveGlobalObtrusiveTaskCount(); - let { apiKey } = response; - let { userName, displayName, _id: userId } = response.user; + let { apiKey } = response; + let { userName, displayName, _id: userId } = response.user; - storedUser.set({ userName, displayName, userId }); - storedSession.set({ apiKey, serverUrl: $server.value }); + storedUser.set({ userName, displayName, userId }); + storedSession.set({ apiKey, serverUrl: $server.value }); - suggestedServerUrl.set($server.value); + suggestedServerUrl.set($server.value); - replace("/dashboard"); + replace("/dashboard"); + } catch (ex) { + return await handleAnyError(ex); + } }; const server = standardField("server", $suggestedServerUrl, [minlength(4)]); diff --git a/src/constant/client-errors.ts b/src/constant/client-errors.ts index c62e3e3..e3cb4bc 100644 --- a/src/constant/client-errors.ts +++ b/src/constant/client-errors.ts @@ -1,18 +1,34 @@ -export const clientError = { - DECRYPTION_FAILED: { - code: "DECRYPTION_FAILED", +export const clientErrorDef = { + NKCE_DECRYPTION_FAILED: { + code: "NKCE_DECRYPTION_FAILED", message: "Failed to decrypt the file. Most likely the file has been corrupted during transmission to or storage on the server.", shorthand: "Decryption failed", }, - ENCRYPTED_DOWNLOAD_FAILED: { - code: "ENCRYPTED_DOWNLOAD_FAILED", - message: "Failed to download encrypted file from the server", + NKCE_ENCRYPTED_DOWNLOAD_FAILED: { + code: "NKCE_ENCRYPTED_DOWNLOAD_FAILED", + message: "Failed to download encrypted file from the server.", shorthand: "Download failed", }, - FAILED_TO_SAVE_FILE: { - code: "FAILED_TO_SAVE_FILE", - message: "Failed to save file after decryption", + NKCE_FAILED_TO_SAVE_FILE: { + code: "NKCE_FAILED_TO_SAVE_FILE", + message: "Failed to save file after decryption.", shorthand: "Filesystem failure", }, + NKCE_BLOB_ID_MISSING: { + code: "NKCE_BLOB_ID_MISSING", + message: "BlobId is missing in server response.", + shorthand: "Filesystem failure", + }, + NKRE_MALFORMATTED_RESPONSE: { + code: "NKRE_MALFORMATTED_RESPONSE", + message: "Server returned a malformatted response.", + shorthand: "Malformatted response", + }, + NKRE_CONNECTIVITY_ISSUE: { + code: "NKRE_CONNECTIVITY_ISSUE", + message: + "Failed to establish a connection with the server. Please make sure you have a working internet connection. If you believe, everything is in working order on your end, please contact server administrator.", + shorthand: "Connection failed", + }, }; diff --git a/src/lib/crypto-transit-basic.ts b/src/lib/crypto-transit-basic.ts index c5f9adc..5358645 100644 --- a/src/lib/crypto-transit-basic.ts +++ b/src/lib/crypto-transit-basic.ts @@ -18,13 +18,8 @@ import { buildCryptoHeader, unbuildCryptoHeader, } from "../utility/crypto-api-utils.js"; -import { clientError } from "../constant/client-errors.js"; -import { - CodedError, - handleErrorIfAny, - raiseCaughtClientError, - raiseClientError, -} from "./error-handling.js"; +import { clientErrorDef } from "../constant/client-errors.js"; +import { raiseCaughtClientError } from "./error-handling.js"; import { BLOB_CHUNK_SIZE_BYTES, ENCRYPTION_TAGLENGTH_IN_BITS, @@ -223,7 +218,6 @@ export const downloadAndDecryptFile = async ( fileId, progressNotifierFn ); - if (await handleErrorIfAny(response)) return null; let { cryptoHeaderContent, arrayBuffer } = response; @@ -238,13 +232,13 @@ export const downloadAndDecryptFile = async ( progressNotifierFn ); } catch (ex) { - throw raiseCaughtClientError(ex, clientError.DECRYPTION_FAILED); + throw raiseCaughtClientError(ex, clientErrorDef.NKCE_DECRYPTION_FAILED); } try { initiateFileDownload(decryptedArrayBuffer, fileNameForDownloading); } catch (ex) { - throw raiseCaughtClientError(ex, clientError.FAILED_TO_SAVE_FILE); + throw raiseCaughtClientError(ex, clientErrorDef.NKCE_FAILED_TO_SAVE_FILE); } return true; diff --git a/src/lib/crypto-transit-stream.ts b/src/lib/crypto-transit-stream.ts index 919832e..529bd51 100644 --- a/src/lib/crypto-transit-stream.ts +++ b/src/lib/crypto-transit-stream.ts @@ -27,12 +27,13 @@ import { IV_LENGTH, SALT_LENGTH, } from "../constant/crypto-specs.js"; -import { CodedError, handleErrorIfAny } from "./error-handling.js"; +import { raiseClientError } from "./error-handling.js"; import streamSaver from "streamsaver"; import { CommonConstant } from "../constant/common-constants.js"; import { storedSession, _storedSession } from "../store/session.js"; import { joinUrlPathFragments } from "../utility/api-utils.js"; +import { clientErrorDef } from "../constant/client-errors.js"; const createCipherProperties = async (bucketPassword: string) => { let { iv } = await makeRandomIv(); @@ -53,7 +54,10 @@ const createEncryptedPseudoTransformStream = async ( let inputStream: ReadableStream = file.stream() as any; // let inputStreamReader = inputStream.getReader(); - let meteredByteReader = new MeteredByteStreamReader(inputStream, "PlaintextStreamForEncryption"); + let meteredByteReader = new MeteredByteStreamReader( + inputStream, + "PlaintextStreamForEncryption" + ); // Note: We are not using transform streams due to a lack of browser support. return new ReadableStream({ @@ -153,13 +157,8 @@ const collectChunksAndUploadFromStream = async ( shouldEnd ); - if (await handleErrorIfAny(response)) return null; - if (!response.blobId) { - throw new CodedError( - "BLOBID_NOT_GIVEN", - "BlobId was not propagated by server" - ); + raiseClientError(clientErrorDef.NKCE_BLOB_ID_MISSING); } blobId = response.blobId; @@ -214,7 +213,10 @@ const createDeryptedPseudoTransformStream = async ( let bytesRead = 0; progressNotifierFn(totalBytes, 0, 0); - let meteredByteReader = new MeteredByteStreamReader(inputStream, "EncryptedStreamForDecryption"); + let meteredByteReader = new MeteredByteStreamReader( + inputStream, + "EncryptedStreamForDecryption" + ); // Note: We are not using transform streams due to a lack of browser support. return new ReadableStream({ @@ -265,7 +267,6 @@ export const downloadAndDecryptFile = async ( progressNotifierFn: Function ) => { let response = await callBlobReadStreamApi(bucketId, fileId); - if (await handleErrorIfAny(response)) return null; let { readableStream, cryptoHeaderContent, contentLengthOnServer } = response; diff --git a/src/lib/error-handling.ts b/src/lib/error-handling.ts index b38a42e..899b562 100644 --- a/src/lib/error-handling.ts +++ b/src/lib/error-handling.ts @@ -1,16 +1,37 @@ +import { clientErrorDef } from "../constant/client-errors.js"; import { decrementActiveGlobalObtrusiveTaskCount, showAlert, } from "../store/ui.js"; import { performUserLogout } from "./session.js"; -export const handleErrorIfAny = async ( - response, +export const handleAnyError = async ( + error: Error, reduceObtrusiveLoader: boolean = true ): Promise => { - if (!response.hasError) return false; - let { message, code } = response.error; - await showAlert("Error occurred", message); + if (!error || "object" !== typeof error || !(error instanceof Error)) { + console.log("Unknown type of error found."); + console.error(error); + await showAlert("Error occurred", "An unknown type of error occurred."); + return; + } + + let code = null; + let title = "Error occurred"; + if (error instanceof CodedError) { + let logMessage = `(Handled) ${error.name}: ${error.code} - ${error.message}`; + console.error(logMessage); + + if (error.code in clientErrorDef) { + title = clientErrorDef[error.code].shorthand; + } + } else { + let logMessage = `(Handled) ${error.name}: ${error.message}`; + console.error(logMessage); + } + + let message = error.message || "An unidentified error occurred"; + await showAlert(title, message); if (reduceObtrusiveLoader) { decrementActiveGlobalObtrusiveTaskCount(); @@ -24,6 +45,21 @@ export const handleErrorIfAny = async ( return true; }; +export const executeAndHandle = async ( + fn: Function, + reduceObtrusiveLoader: boolean = true +): Promise<[any, boolean]> => { + let hadError = false; + let response; + try { + response = await fn(); + } catch (ex) { + await handleAnyError(ex, reduceObtrusiveLoader); + hadError = true; + } + return [response, hadError]; +}; + class ExtendableError extends Error { constructor(message: string) { super(message); @@ -45,17 +81,24 @@ export class CodedError extends ExtendableError { } } +export class ClientError extends CodedError {} + +export class ResponseError extends CodedError {} + export function raiseCaughtClientError( - exception: Error, - clientError, + caughtError: Error, + clientErrorDef, message: string = null ) { - console.error("Caught and proxied:", exception); - let error = raiseClientError(clientError, message); - error.cause = exception; + console.error("Caught and proxied:", caughtError); + let error = raiseClientError(clientErrorDef, message); + error.cause = caughtError; return error; } -export function raiseClientError(clientError, message: string = null) { - return new CodedError(clientError.code, message || clientError.message); +export function raiseClientError(clientErrorDef, message: string = null) { + return new ClientError( + clientErrorDef.code, + message || clientErrorDef.message + ); } diff --git a/src/store/ui.ts b/src/store/ui.ts index 7b3c179..86b903e 100644 --- a/src/store/ui.ts +++ b/src/store/ui.ts @@ -1,7 +1,7 @@ import { Writable, writable } from "svelte/store"; import type { User } from "src/model/common.js"; -import { CodedError } from "../lib/error-handling.js"; -import { clientError } from "../constant/client-errors.js"; +import { ClientError } from "../lib/error-handling.js"; +import { clientErrorDef } from "../constant/client-errors.js"; let inflatedZIndex = 8; const STARTING_Z_INDEX = 8; @@ -132,8 +132,8 @@ export let showCommonErrorDialog = async (ex: Error) => { let message = "An unknown error occurred."; if (ex && "object" === typeof ex) { - if (ex instanceof CodedError && ex.code in clientError) { - title = clientError[ex.code].shorthand; + if (ex instanceof ClientError && ex.code in clientErrorDef) { + title = clientErrorDef[ex.code].shorthand; } if (ex.message) { diff --git a/src/utility/api-utils.ts b/src/utility/api-utils.ts index bf0c402..a368c7b 100644 --- a/src/utility/api-utils.ts +++ b/src/utility/api-utils.ts @@ -1,11 +1,8 @@ -import { clientError } from "../constant/client-errors.js"; -import { CodedError, raiseClientError } from "../lib/error-handling.js"; +import { clientErrorDef } from "../constant/client-errors.js"; +import { raiseClientError, ResponseError } from "../lib/error-handling.js"; import { BLOB_API_CRYPTO_META_HEADER_NAME } from "../constant/crypto-specs.js"; import { convertStreamToBuffer } from "./stream-and-buffer-utils.js"; -const genericConnectionFailureMessage = - "Failed to establish a connection with the server. Please make sure you have a working internet connection. If you believe, everything is in working order on your end, please contact server administrator."; - export const joinUrlPathFragments = (...pathFragments: string[]) => { return pathFragments.map((str) => str.replace(/^\/+|\/+$/g, "")).join("/"); }; @@ -33,21 +30,25 @@ export const callPostJsonApi = async ( }; let responseJson = null; - let responseObject = null; - try { - responseObject = await fetch(url, options); - responseJson = await responseObject.json(); + let fetchResponse = await fetch(url, options); + responseJson = await fetchResponse.json(); } catch (ex) { console.error(ex); - responseJson = { - hasError: true, - error: { - code: "SERVER_CONNECTION_FAILURE", - message: genericConnectionFailureMessage, - details: {}, - }, - }; + throw new ResponseError( + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.code, + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.message + ); + } + + if (responseJson.hasError) { + let code = + responseJson.error?.code || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.code; + let message = + responseJson.error?.message || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.message; + throw new ResponseError(code, message); } return responseJson; @@ -83,20 +84,25 @@ export const callPostStreamUploadApi = async ( }; let responseJson = null; - let responseObject = null; try { - responseObject = await fetch(url, options); - responseJson = await responseObject.json(); + let fetchResponse = await fetch(url, options); + responseJson = await fetchResponse.json(); } catch (ex) { console.error(ex); - responseJson = { - hasError: true, - error: { - code: "SERVER_CONNECTION_FAILURE", - message: genericConnectionFailureMessage, - details: {}, - }, - }; + throw new ResponseError( + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.code, + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.message + ); + } + + if (responseJson.hasError) { + let code = + responseJson.error?.code || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.code; + let message = + responseJson.error?.message || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.message; + throw new ResponseError(code, message); } return responseJson; @@ -124,29 +130,34 @@ export const callPostStreamDownloadApi = async ( }; let responseJson = null; - let responseObject = null; try { - responseObject = await fetch(url, options); + let fetchResponse = await fetch(url, options); responseJson = { hasError: false, - readableStream: responseObject.body, - cryptoHeaderContent: responseObject.headers.get( + readableStream: fetchResponse.body, + cryptoHeaderContent: fetchResponse.headers.get( BLOB_API_CRYPTO_META_HEADER_NAME ), contentLengthOnServer: parseInt( - responseObject.headers.get("Content-Length") + fetchResponse.headers.get("Content-Length") ), }; } catch (ex) { console.error(ex); - responseJson = { - hasError: true, - error: { - code: "SERVER_CONNECTION_FAILURE", - message: genericConnectionFailureMessage, - details: {}, - }, - }; + throw new ResponseError( + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.code, + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.message + ); + } + + if (responseJson.hasError) { + let code = + responseJson.error?.code || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.code; + let message = + responseJson.error?.message || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.message; + throw new ResponseError(code, message); } return responseJson; @@ -208,14 +219,20 @@ export const callPostArrayBufferUploadApi = async ( responseJson = JSON.parse(responseObject.responseText); } catch (ex) { console.error(ex); - responseJson = { - hasError: true, - error: { - code: "SERVER_CONNECTION_FAILURE", - message: genericConnectionFailureMessage, - details: {}, - }, - }; + throw new ResponseError( + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.code, + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.message + ); + } + + if (responseJson.hasError) { + let code = + responseJson.error?.code || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.code; + let message = + responseJson.error?.message || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.message; + throw new ResponseError(code, message); } return responseJson; @@ -252,21 +269,11 @@ export const callPostArrayBufferDownloadApi = async ( }; xhr.onerror = (event) => { - let error = raiseClientError(clientError.ENCRYPTED_DOWNLOAD_FAILED); - (error).details = { - xhr, - event, - }; - reject(error); + reject(xhr); }; xhr.onabort = (event) => { - let error = raiseClientError(clientError.ENCRYPTED_DOWNLOAD_FAILED); - (error).details = { - xhr, - event, - }; - reject(error); + reject(xhr); }; xhr.send("{}"); @@ -282,14 +289,20 @@ export const callPostArrayBufferDownloadApi = async ( }; } catch (ex) { console.error(ex); - responseJson = { - hasError: true, - error: { - code: "SERVER_CONNECTION_FAILURE", - message: genericConnectionFailureMessage, - details: {}, - }, - }; + throw new ResponseError( + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.code, + clientErrorDef.NKRE_CONNECTIVITY_ISSUE.message + ); + } + + if (responseJson.hasError) { + let code = + responseJson.error?.code || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.code; + let message = + responseJson.error?.message || + clientErrorDef.NKRE_MALFORMATTED_RESPONSE.message; + throw new ResponseError(code, message); } return responseJson;