mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-27 02:01:02 -04:00
* 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
110 lines
2.5 KiB
TypeScript
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 };
|
|
}
|