1
Fork 0
mirror of https://github.com/Steffo99/festa.git synced 2024-12-22 14:44:21 +00:00

Improve error-related components

This commit is contained in:
Steffo 2022-07-19 19:51:14 +02:00
parent 08ed0f14d3
commit e78532243d
Signed by: steffo
GPG key ID: 6965406171929D01
3 changed files with 57 additions and 16 deletions

View file

@ -1,6 +1,6 @@
import { Component, ErrorInfo, ReactNode } from "react";
import { ViewNotice } from "../views/notice";
import { ErrorBlock, ErrorMain } from "./renderers";
import { ErrorBlock, ErrorInline, ErrorMain, ErrorView } from "./renderers";
export type ErrorBoundaryProps = {
@ -20,7 +20,7 @@ export type ErrorBoundaryState = {
*
* To be used in `pages/_app`.
*/
export class ErrorBoundaryPage extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
export class ErrorBoundaryView extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
constructor(props: ErrorBoundaryProps) {
super(props)
this.state = { error: undefined, errorInfo: undefined }
@ -35,11 +35,7 @@ export class ErrorBoundaryPage extends Component<ErrorBoundaryProps, ErrorBounda
render() {
if (this.state.error) {
return (
<ViewNotice
notice={
<ErrorMain text={this.props.text} error={this.state.error} />
}
/>
<ErrorView text={this.props.text} error={this.state.error} />
)
}
else {
@ -76,4 +72,34 @@ export class ErrorBoundaryBlock extends Component<ErrorBoundaryProps, ErrorBound
return this.props.children
}
}
}
/**
* Error boundary component which displays an {@link ErrorInline} containing the occurred error inside.
*
* To be used in other components.
*/
export class ErrorBoundaryInline extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
constructor(props: ErrorBoundaryProps) {
super(props)
this.state = { error: undefined, errorInfo: undefined }
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
this.setState(state => {
return { ...state, error, errorInfo }
})
}
render() {
if (this.state.error) {
return (
<ErrorInline text={this.props.text} error={this.state.error} />
)
}
else {
return this.props.children
}
}
}

View file

@ -5,6 +5,7 @@ import style from "./renderers.module.css"
import mood from "../../../styles/mood.module.css"
import { ComponentPropsWithoutRef, memo } from "react";
import { AxiosError } from "axios";
import { ViewNotice } from "../views/notice";
/**
@ -149,13 +150,15 @@ ErrorBlock.displayName = "ErrorBlock"
*
* It displays an inline error {@link FestaIcon}, followed by some **required** text, with the {@link ErrorTrace} below.
*/
export const ErrorMain = memo(({ error, text }: ErrorProps & { text: string }) => {
export const ErrorMain = memo(({ error, text }: ErrorProps) => {
return (
<div className={classNames(mood.negative, style.error, style.errorMain)}>
<FestaIcon icon={faCircleExclamation} className={style.errorIcon} />
<p className={style.errorText}>
{text}
</p>
{text &&
<p className={style.errorText}>
{text}
</p>
}
<pre>
<ErrorTrace error={error} prettify={false} className={style.errorTrace} />
</pre>
@ -163,3 +166,15 @@ export const ErrorMain = memo(({ error, text }: ErrorProps & { text: string }) =
)
})
ErrorMain.displayName = "ErrorMain"
/**
* {@link ViewNotice} component for rendering {@link ErrorMain}.
*/
export const ErrorView = memo((props: ErrorProps) => {
return (
<ViewNotice
notice={<ErrorMain {...props} />}
/>
)
})

View file

@ -3,7 +3,7 @@ import '@fortawesome/fontawesome-svg-core/styles.css'
import { AppProps } from 'next/app'
import { appWithTranslation, useTranslation } from 'next-i18next'
import { AxiosSWRFetcherProvider } from '../components/auth/requests'
import { ErrorBoundaryPage } from '../components/generic/errors/boundaries'
import { ErrorBoundaryView } from '../components/generic/errors/boundaries'
import { AuthContextProvider } from '../components/auth/provider'
import { PostcardRenderer } from '../components/postcard/renderer'
import { config as fontAwesomeConfig } from '@fortawesome/fontawesome-svg-core'
@ -19,22 +19,22 @@ const App = ({ Component, pageProps }: AppProps): JSX.Element => {
const { t } = useTranslation()
return (
<ErrorBoundaryPage text={t("genericError")}>
<ErrorBoundaryView text={t("genericError")}>
<AxiosSWRFetcherProvider>
<PostcardContextProvider defaultPostcard={defaultPostcard}>
<AuthContextProvider storageKey="auth">
<AxiosSWRFetcherProvider>
<PostcardRenderer />
<ErrorBoundaryPage text={t("genericError")}>
<ErrorBoundaryView text={t("genericError")}>
<LoadingBoundaryPage>
<Component {...pageProps} />
</LoadingBoundaryPage>
</ErrorBoundaryPage>
</ErrorBoundaryView>
</AxiosSWRFetcherProvider>
</AuthContextProvider>
</PostcardContextProvider>
</AxiosSWRFetcherProvider>
</ErrorBoundaryPage>
</ErrorBoundaryView>
)
}