Files
freeCodeCamp/client/src/utils/handled-error.ts
awu43 e1d8f4be3a feat(client): ts-migrate client/src/utils (#42666)
* rename js files to ts

* start migrating ajax

* finish migrating ajax

* migrate algolia-locale-setup

* migrate format

* migrate format.test

* migrate get-words

* install axios for types in handled-error

* migrate handled-error

* migrate handled-error.test

* migrate report-error

* migrate script-loaders

* migrate to-learn-path

* correct renamed imports

* remove unnecessary type assertions in searchBar

* remove unnecessary global comment

* remove unnecessary max-len enable/disable

* change axios imports to type imports

* revert to .then() from await

* use UserType from redux/prop-types

* replace assertion with generic type

* revert format to JS

* remove unused getArticleById()

* update putUpdateUserFlag() to use Record

* remove unnecessary envData cast

* update algolia-locale-setup types

* remove invalid key property
2021-07-12 11:17:58 +02:00

110 lines
2.5 KiB
TypeScript

import { has } from 'lodash-es';
import type { AxiosError, AxiosResponse } from 'axios';
import standardErrorMessage from './standard-error-message';
import reportedErrorMessage from './reported-error-message';
import { reportClientSideError } from './report-error';
interface ErrorData {
type?: string;
message?: string;
redirectTo?: string | null;
}
export const handledErrorSymbol = Symbol('handledError');
export type HandledError = Error & {
[handledErrorSymbol]: ErrorData;
};
export function isHandledError(err: unknown): err is HandledError {
return has(err, handledErrorSymbol);
}
export function unwrapHandledError(
err: HandledError
): ErrorData | Record<string, never> {
return handledErrorSymbol in err ? err[handledErrorSymbol] : {};
}
export function wrapHandledError(
err: Error,
{ type, message, redirectTo }: ErrorData
): HandledError {
(err as HandledError)[handledErrorSymbol] = {
type,
message,
redirectTo
};
return err as HandledError;
}
export function handle400Error(
e: AxiosError,
options: ErrorData = { redirectTo: '/' }
): ErrorData {
const { status } = e.response as AxiosResponse;
const { redirectTo } = options;
const flash = { ...standardErrorMessage, redirectTo };
switch (status) {
case 401:
case 403: {
return {
...flash,
type: 'warn',
message: 'flash.not-authorized'
};
}
case 404: {
return {
...flash,
type: 'info',
message: 'flash.could-not-find'
};
}
default: {
return flash;
}
}
}
export function handle500Error(
e: AxiosError,
options: ErrorData = {
redirectTo: '/'
},
_reportClientSideError: (
e: Error,
message: string
) => void = reportClientSideError
): ErrorData {
const { redirectTo } = options;
_reportClientSideError(e, 'We just handled a 5** error on the client');
return { ...reportedErrorMessage, redirectTo };
}
export function handleAPIError(
e: AxiosError,
options: ErrorData,
_reportClientSideError: (
e: Error,
message: string
) => void = reportClientSideError
): ErrorData {
const { response: { status = 0 } = {} } = e;
if (status >= 400 && status < 500) {
return handle400Error(e, options);
}
if (status >= 500) {
return handle500Error(e, options, _reportClientSideError);
}
const { redirectTo } = options;
_reportClientSideError(
e,
'We just handled an api error on the client without an error status code'
);
return { ...reportedErrorMessage, redirectTo };
}