2022-06-11 03:08:49 +00:00
|
|
|
import { faCircleExclamation } from "@fortawesome/free-solid-svg-icons";
|
|
|
|
import { FestaIcon } from "../renderers/fontawesome";
|
|
|
|
import { default as classNames } from "classnames"
|
|
|
|
import style from "./renderers.module.css"
|
2022-07-18 22:42:56 +00:00
|
|
|
import mood from "../../../styles/mood.module.css"
|
|
|
|
import { ComponentPropsWithoutRef, memo } from "react";
|
2022-06-11 03:08:49 +00:00
|
|
|
import { AxiosError } from "axios";
|
2022-07-19 17:51:14 +00:00
|
|
|
import { ViewNotice } from "../views/notice";
|
2022-06-11 03:08:49 +00:00
|
|
|
|
|
|
|
|
2022-07-18 22:42:56 +00:00
|
|
|
/**
|
|
|
|
* Props of {@link ErrorTrace}.
|
|
|
|
*/
|
|
|
|
type ErrorTraceProps = ComponentPropsWithoutRef<"code"> & {
|
|
|
|
/**
|
|
|
|
* The error to render the stack trace of.
|
|
|
|
*/
|
2022-06-11 03:08:49 +00:00
|
|
|
error: Error,
|
2022-07-18 22:42:56 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether error messages in JSON format should be prettified or not.
|
|
|
|
*/
|
|
|
|
prettify: boolean,
|
2022-06-11 03:08:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-07-18 22:42:56 +00:00
|
|
|
/**
|
|
|
|
* Component rendering the details of an {@link Error}.
|
|
|
|
*
|
|
|
|
* Not to use by itself; should be used to display the error in other error renderers.
|
|
|
|
*/
|
|
|
|
const ErrorTrace = memo(({ error, prettify, ...props }: ErrorTraceProps) => {
|
|
|
|
if (error instanceof AxiosError) {
|
|
|
|
if (error.response) {
|
|
|
|
if (error.response.data) {
|
|
|
|
const json = JSON.stringify(error.response.data, undefined, prettify ? 4 : undefined).replaceAll("\\n", "\n")
|
2022-06-11 03:08:49 +00:00
|
|
|
|
|
|
|
return (
|
2022-07-18 22:42:56 +00:00
|
|
|
<code {...props}>
|
|
|
|
<span>
|
|
|
|
<b>API {error.response.status}</b>
|
|
|
|
:
|
|
|
|
</span>
|
|
|
|
<span>
|
|
|
|
{json}
|
|
|
|
</span>
|
2022-06-11 03:08:49 +00:00
|
|
|
</code>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2022-07-18 22:42:56 +00:00
|
|
|
<code {...props}>
|
|
|
|
<span>
|
|
|
|
<b>HTTP {error.response.status}</b>
|
|
|
|
:
|
|
|
|
</span>
|
|
|
|
<span>
|
|
|
|
{error.message}
|
|
|
|
</span>
|
2022-06-11 03:08:49 +00:00
|
|
|
</code>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2022-07-18 22:42:56 +00:00
|
|
|
<code {...props}>
|
|
|
|
<span>
|
|
|
|
<b>{error.code}</b>
|
|
|
|
:
|
|
|
|
</span>
|
|
|
|
<span>
|
|
|
|
{error.message}
|
|
|
|
</span>
|
2022-06-11 03:08:49 +00:00
|
|
|
</code>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2022-07-18 22:42:56 +00:00
|
|
|
<code {...props}>
|
|
|
|
<span>
|
|
|
|
<b>{error.name}</b>
|
|
|
|
:
|
|
|
|
</span>
|
|
|
|
<span>
|
|
|
|
{error.message}
|
|
|
|
</span>
|
2022-06-11 03:08:49 +00:00
|
|
|
</code>
|
|
|
|
)
|
|
|
|
})
|
2022-07-16 14:14:48 +00:00
|
|
|
ErrorTrace.displayName = "ErrorTrace"
|
2022-06-11 03:08:49 +00:00
|
|
|
|
|
|
|
|
2022-07-18 22:42:56 +00:00
|
|
|
/**
|
|
|
|
* Props for "error" renderers.
|
|
|
|
*/
|
|
|
|
export type ErrorProps = {
|
2022-06-11 03:08:49 +00:00
|
|
|
error: Error,
|
|
|
|
text?: string
|
|
|
|
}
|
|
|
|
|
2022-07-18 22:42:56 +00:00
|
|
|
|
2022-06-11 03:08:49 +00:00
|
|
|
/**
|
2022-07-18 22:42:56 +00:00
|
|
|
* Inline component for rendering errors.
|
2022-06-11 03:08:49 +00:00
|
|
|
*
|
2022-07-18 22:42:56 +00:00
|
|
|
* It displays an error {@link FestaIcon}, followed by some optional text, and finally the {@link ErrorTrace}.
|
2022-06-11 03:08:49 +00:00
|
|
|
*/
|
2022-07-18 22:42:56 +00:00
|
|
|
export const ErrorInline = memo(({ error, text }: ErrorProps) => {
|
2022-06-11 03:08:49 +00:00
|
|
|
return (
|
2022-07-18 22:42:56 +00:00
|
|
|
<span className={classNames(mood.negative, style.error, style.errorInline)}>
|
|
|
|
<FestaIcon icon={faCircleExclamation} className={style.errorIcon} />
|
|
|
|
{!!text && <>
|
|
|
|
|
|
|
|
<span className={style.errorText}>
|
|
|
|
{text}
|
|
|
|
</span>
|
|
|
|
|
|
|
|
</>}
|
|
|
|
<ErrorTrace error={error} prettify={false} className={style.errorTrace} />
|
2022-06-11 03:08:49 +00:00
|
|
|
</span>
|
|
|
|
)
|
|
|
|
})
|
2022-07-16 14:12:29 +00:00
|
|
|
ErrorInline.displayName = "ErrorInline"
|
2022-06-11 03:08:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2022-07-18 22:42:56 +00:00
|
|
|
* Block component for rendering errors.
|
2022-06-11 03:08:49 +00:00
|
|
|
*
|
2022-07-18 22:42:56 +00:00
|
|
|
* It displays an inline error {@link FestaIcon}, followed by some **required** text, with the {@link ErrorTrace} below.
|
2022-06-11 03:08:49 +00:00
|
|
|
*/
|
2022-07-18 22:42:56 +00:00
|
|
|
export const ErrorBlock = memo(({ error, text }: ErrorProps & { text: string }) => {
|
2022-06-11 03:08:49 +00:00
|
|
|
return (
|
2022-07-18 22:42:56 +00:00
|
|
|
<div className={classNames(mood.negative, style.error, style.errorBlock)}>
|
2022-06-11 03:08:49 +00:00
|
|
|
<p>
|
2022-07-18 22:42:56 +00:00
|
|
|
<FestaIcon icon={faCircleExclamation} className={style.errorIcon} />
|
2022-06-11 03:08:49 +00:00
|
|
|
|
2022-07-18 22:42:56 +00:00
|
|
|
<span className={style.errorText}>
|
|
|
|
{text}
|
2022-06-11 03:08:49 +00:00
|
|
|
</span>
|
|
|
|
</p>
|
|
|
|
<pre>
|
2022-07-18 22:42:56 +00:00
|
|
|
<ErrorTrace error={error} prettify={false} className={style.errorTrace} />
|
|
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
})
|
|
|
|
ErrorBlock.displayName = "ErrorBlock"
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Block component for rendering errors at the center of the page.
|
|
|
|
*
|
|
|
|
* It displays an inline error {@link FestaIcon}, followed by some **required** text, with the {@link ErrorTrace} below.
|
|
|
|
*/
|
2022-07-19 17:51:14 +00:00
|
|
|
export const ErrorMain = memo(({ error, text }: ErrorProps) => {
|
2022-07-18 22:42:56 +00:00
|
|
|
return (
|
|
|
|
<div className={classNames(mood.negative, style.error, style.errorMain)}>
|
|
|
|
<FestaIcon icon={faCircleExclamation} className={style.errorIcon} />
|
2022-07-19 17:51:14 +00:00
|
|
|
{text &&
|
|
|
|
<p className={style.errorText}>
|
|
|
|
{text}
|
|
|
|
</p>
|
|
|
|
}
|
2022-07-18 22:42:56 +00:00
|
|
|
<pre>
|
|
|
|
<ErrorTrace error={error} prettify={false} className={style.errorTrace} />
|
2022-06-11 03:08:49 +00:00
|
|
|
</pre>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
})
|
2022-07-18 22:42:56 +00:00
|
|
|
ErrorMain.displayName = "ErrorMain"
|
2022-07-19 17:51:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@link ViewNotice} component for rendering {@link ErrorMain}.
|
|
|
|
*/
|
|
|
|
export const ErrorView = memo((props: ErrorProps) => {
|
|
|
|
return (
|
|
|
|
<ViewNotice
|
|
|
|
notice={<ErrorMain {...props} />}
|
|
|
|
/>
|
|
|
|
)
|
2022-07-19 18:30:28 +00:00
|
|
|
})
|
|
|
|
ErrorView.displayName = "ErrorView"
|