ConceptPortal-public/rsconcept/frontend/src/components/BackendError.tsx

69 lines
2.0 KiB
TypeScript
Raw Normal View History

import axios, { type AxiosError,AxiosHeaderValue } from 'axios';
2023-07-25 20:27:29 +03:00
2023-11-27 12:11:39 +03:00
import PrettyJson from './Common/PrettyJSON';
2023-07-15 17:46:19 +03:00
export type ErrorInfo = string | Error | AxiosError | undefined;
interface BackendErrorProps {
error: ErrorInfo
}
function DescribeError(error: ErrorInfo) {
2023-08-28 00:03:31 +03:00
reportError(error);
2023-07-15 17:46:19 +03:00
if (!error) {
return <p>Ошибки отсутствуют</p>;
} else if (typeof error === 'string') {
return <p>{error}</p>;
} else if (!axios.isAxiosError(error)) {
return <PrettyJson data={error} />;
}
if (!error?.response) {
return <p>Нет ответа от сервера</p>;
}
if (error.response.status === 404) {
2023-07-15 17:46:19 +03:00
return (
<div className='flex flex-col justify-start'>
2023-07-25 20:27:29 +03:00
<p>{'Обращение к несуществующему API'}</p>
<PrettyJson data={error} />
2023-07-15 17:46:19 +03:00
</div>
);
}
2023-07-25 20:27:29 +03:00
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const isHtml = (() => {
if (!error.response) {
return false;
}
const header = error.response.headers['content-type'] as AxiosHeaderValue;
if (!header) {
return false;
}
if (typeof header === 'number' || typeof header === 'boolean') {
return false;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
return header.includes('text/html');
})();
return (
<div className='flex flex-col justify-start'>
<p className='underline'>Ошибка</p>
<p>{error.message}</p>
{error.response.data && (<>
<p className='mt-2 underline'>Описание</p>
{isHtml ? <div dangerouslySetInnerHTML={{ __html: error.response.data as TrustedHTML }} /> : null}
{!isHtml ? <PrettyJson data={error.response.data as object} /> : null}
</>)}
</div>
);
2023-07-15 17:46:19 +03:00
}
2023-07-25 20:27:29 +03:00
function BackendError({ error }: BackendErrorProps) {
2023-07-15 17:46:19 +03:00
return (
2023-09-18 15:25:25 +03:00
<div className='px-3 py-2 min-w-[15rem] text-sm font-semibold select-text text-warning'>
2023-07-15 17:46:19 +03:00
{DescribeError(error)}
</div>
);
}
2023-07-25 20:27:29 +03:00
export default BackendError;