From b78d21a524f7a11ad29b4bd230f23825f80c3ed7 Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 26 Jul 2020 15:02:55 +0800 Subject: Merge front end repo --- Timeline/ClientApp/src/app/http/common.ts | 140 ++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 Timeline/ClientApp/src/app/http/common.ts (limited to 'Timeline/ClientApp/src/app/http/common.ts') diff --git a/Timeline/ClientApp/src/app/http/common.ts b/Timeline/ClientApp/src/app/http/common.ts new file mode 100644 index 00000000..8fb8eb69 --- /dev/null +++ b/Timeline/ClientApp/src/app/http/common.ts @@ -0,0 +1,140 @@ +import { AxiosError, AxiosResponse } from 'axios'; + +export const apiBaseUrl = '/api'; + +export function base64(blob: Blob): Promise { + return new Promise((resolve) => { + const reader = new FileReader(); + reader.onload = function () { + resolve((reader.result as string).replace(/^data:.+;base64,/, '')); + }; + reader.readAsDataURL(blob); + }); +} + +export function extractStatusCode(error: AxiosError): number | null { + if (error.isAxiosError) { + const code = error?.response?.status; + if (typeof code === 'number') { + return code; + } + } + return null; +} + +export interface CommonErrorResponse { + code: number; + message: string; +} + +export function extractErrorCode( + error: AxiosError +): number | null { + if (error.isAxiosError) { + const code = error.response?.data?.code; + if (typeof code === 'number') { + return code; + } + } + return null; +} + +export class HttpNetworkError extends Error { + constructor(public innerError?: AxiosError) { + super(); + } +} + +export class NotModified {} + +export interface BlobWithEtag { + data: Blob; + etag: string; +} + +export function extractResponseData(res: AxiosResponse): T { + return res.data; +} + +export function catchIfStatusCodeIs< + TResult, + TErrorHandlerResult extends TResult | PromiseLike | null | undefined +>( + statusCode: number, + errorHandler: (error: AxiosError) => TErrorHandlerResult +): (error: AxiosError) => TErrorHandlerResult { + return (error: AxiosError) => { + if (extractStatusCode(error) == statusCode) { + return errorHandler(error); + } else { + throw error; + } + }; +} + +export function convertToIfStatusCodeIs( + statusCode: number, + newErrorType: { + new (innerError: AxiosError): NewError; + } +): (error: AxiosError) => never { + return catchIfStatusCodeIs(statusCode, (error) => { + throw new newErrorType(error); + }); +} + +export function catchIfErrorCodeIs< + TResult, + TErrorHandlerResult extends TResult | PromiseLike | null | undefined +>( + errorCode: number, + errorHandler: (error: AxiosError) => TErrorHandlerResult +): (error: AxiosError) => TErrorHandlerResult { + return (error: AxiosError) => { + if (extractErrorCode(error) == errorCode) { + return errorHandler(error); + } else { + throw error; + } + }; +} +export function convertToIfErrorCodeIs( + errorCode: number, + newErrorType: { + new (innerError: AxiosError): NewError; + } +): (error: AxiosError) => never { + return catchIfErrorCodeIs(errorCode, (error) => { + throw new newErrorType(error); + }); +} + +export function convertToNetworkError( + error: AxiosError +): never { + if (error.isAxiosError && error.response == null) { + throw new HttpNetworkError(error); + } else { + throw error; + } +} + +export function convertToBlobWithEtag(res: AxiosResponse): BlobWithEtag { + return { + data: res.data, + etag: (res.headers as Record<'etag', string>)['etag'], + }; +} + +export function convertToBlobWithEtagOrNotModified( + res: AxiosResponse +): BlobWithEtag | NotModified { + if (res.status === 304) { + return new NotModified(); + } else { + return { + data: res.data, + etag: (res.headers as Record<'etag', string>)['etag'], + }; + } +} -- cgit v1.2.3