create api-error error subclass. checks status for error handling when reading compliance info

This commit is contained in:
Seyi Adebajo 2018-02-22 14:26:19 -08:00
parent 86804ac2c9
commit 543a72d364
4 changed files with 47 additions and 16 deletions

View File

@ -1,14 +1,14 @@
import { ApiStatusNumber } from 'wherehows-web/utils/api/shared';
import { ApiResponseStatus } from 'wherehows-web/utils/api/shared';
/**
* Returns a default msg for a given status
* @param {ApiStatusNumber} status
* @param {ApiResponseStatus} status
* @returns {string}
*/
const apiErrorStatusMessage = (status: ApiStatusNumber): string =>
const apiErrorStatusMessage = (status: ApiResponseStatus): string =>
(<{ [prop: number]: string }>{
[ApiStatusNumber.NotFound]: 'Could not find the requested resource',
[ApiStatusNumber.InternalServerError]: 'An error occurred with the server'
[ApiResponseStatus.NotFound]: 'Could not find the requested resource',
[ApiResponseStatus.InternalServerError]: 'An error occurred with the server'
})[status];
export { apiErrorStatusMessage };

View File

@ -1,4 +1,6 @@
import { assert } from '@ember/debug';
import { ApiResponseStatus } from 'wherehows-web/utils/api';
import { ApiError } from 'wherehows-web/utils/api/errors/errors';
import { createInitialComplianceInfo } from 'wherehows-web/utils/datasets/compliance-policy';
import { datasetUrlById, datasetUrlByUrn } from 'wherehows-web/utils/api/datasets/shared';
import { ApiStatus } from 'wherehows-web/utils/api/shared';
@ -82,18 +84,24 @@ const readDatasetCompliance = async (id: number): Promise<IReadComplianceResult>
};
/**
* Reads the dataset compliance policy by urn
* @param {string} urn
* Reads the dataset compliance policy by urn.
* Resolves with a new compliance policy instance if remote response is ApiResponseStatus.NotFound
* @param {string} urn the urn for the related dataset
* @return {Promise<IReadComplianceResult>}
*/
const readDatasetComplianceByUrn = async (urn: string): Promise<IReadComplianceResult> => {
let { complianceInfo } = await getJSON<Pick<IComplianceGetResponse, 'complianceInfo'>>({
url: datasetComplianceUrlByUrn(urn)
});
const isNewComplianceInfo = !complianceInfo;
let complianceInfo: IComplianceGetResponse['complianceInfo'];
let isNewComplianceInfo = false;
if (isNewComplianceInfo) {
try {
({ complianceInfo } = await getJSON<Pick<IComplianceGetResponse, 'complianceInfo'>>({
url: datasetComplianceUrlByUrn(urn)
}));
} catch (e) {
if (e instanceof ApiError && e.status === ApiResponseStatus.NotFound) {
complianceInfo = createInitialComplianceInfo(urn);
isNewComplianceInfo = true;
}
}
return { isNewComplianceInfo, complianceInfo: complianceInfo! };

View File

@ -1,4 +1,27 @@
import { apiErrorStatusMessage } from 'wherehows-web/constants/errors/errors';
import { ApiResponseStatus } from 'wherehows-web/utils/api';
/**
* Extends the built-in Error class with attributes related to treating non 200 OK responses
* at the api layer as exceptions
* @class ApiError
* @extends {Error}
*/
class ApiError extends Error {
/**
* Timestamp of when the exception occurred
* @readonly
* @memberof ApiError
*/
readonly timestamp = new Date();
constructor(readonly status: ApiResponseStatus, message: string, ...args: Array<any>) {
super(...[message, ...args]);
// Fixes downlevel compiler limitation with correct prototype chain adjustment
// i.e. ensuring this is also `instanceof` subclass
Object.setPrototypeOf(this, ApiError.prototype);
}
}
/**
* Wraps a Response object, pass through json response if no api error,
@ -12,10 +35,10 @@ const throwIfApiError = async <T>(response: Response): Promise<T> => {
if (!ok) {
const { msg = apiErrorStatusMessage(status) } = await response.json();
throw new Error(msg);
throw new ApiError(status, msg);
}
return response.json();
};
export { throwIfApiError };
export { throwIfApiError, ApiError };

View File

@ -26,7 +26,7 @@ export enum ApiStatus {
* Enumerates the currently available Api statuses
* @type {number}
*/
export enum ApiStatusNumber {
export enum ApiResponseStatus {
NotFound = 404,
UnAuthorized = 401,
InternalServerError = 500