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:
parent
08ed0f14d3
commit
e78532243d
3 changed files with 57 additions and 16 deletions
|
@ -1,6 +1,6 @@
|
||||||
import { Component, ErrorInfo, ReactNode } from "react";
|
import { Component, ErrorInfo, ReactNode } from "react";
|
||||||
import { ViewNotice } from "../views/notice";
|
import { ViewNotice } from "../views/notice";
|
||||||
import { ErrorBlock, ErrorMain } from "./renderers";
|
import { ErrorBlock, ErrorInline, ErrorMain, ErrorView } from "./renderers";
|
||||||
|
|
||||||
|
|
||||||
export type ErrorBoundaryProps = {
|
export type ErrorBoundaryProps = {
|
||||||
|
@ -20,7 +20,7 @@ export type ErrorBoundaryState = {
|
||||||
*
|
*
|
||||||
* To be used in `pages/_app`.
|
* To be used in `pages/_app`.
|
||||||
*/
|
*/
|
||||||
export class ErrorBoundaryPage extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
export class ErrorBoundaryView extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
||||||
constructor(props: ErrorBoundaryProps) {
|
constructor(props: ErrorBoundaryProps) {
|
||||||
super(props)
|
super(props)
|
||||||
this.state = { error: undefined, errorInfo: undefined }
|
this.state = { error: undefined, errorInfo: undefined }
|
||||||
|
@ -35,11 +35,7 @@ export class ErrorBoundaryPage extends Component<ErrorBoundaryProps, ErrorBounda
|
||||||
render() {
|
render() {
|
||||||
if (this.state.error) {
|
if (this.state.error) {
|
||||||
return (
|
return (
|
||||||
<ViewNotice
|
<ErrorView text={this.props.text} error={this.state.error} />
|
||||||
notice={
|
|
||||||
<ErrorMain text={this.props.text} error={this.state.error} />
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -76,4 +72,34 @@ export class ErrorBoundaryBlock extends Component<ErrorBoundaryProps, ErrorBound
|
||||||
return this.props.children
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@ import style from "./renderers.module.css"
|
||||||
import mood from "../../../styles/mood.module.css"
|
import mood from "../../../styles/mood.module.css"
|
||||||
import { ComponentPropsWithoutRef, memo } from "react";
|
import { ComponentPropsWithoutRef, memo } from "react";
|
||||||
import { AxiosError } from "axios";
|
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.
|
* 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 (
|
return (
|
||||||
<div className={classNames(mood.negative, style.error, style.errorMain)}>
|
<div className={classNames(mood.negative, style.error, style.errorMain)}>
|
||||||
<FestaIcon icon={faCircleExclamation} className={style.errorIcon} />
|
<FestaIcon icon={faCircleExclamation} className={style.errorIcon} />
|
||||||
<p className={style.errorText}>
|
{text &&
|
||||||
{text}
|
<p className={style.errorText}>
|
||||||
</p>
|
{text}
|
||||||
|
</p>
|
||||||
|
}
|
||||||
<pre>
|
<pre>
|
||||||
<ErrorTrace error={error} prettify={false} className={style.errorTrace} />
|
<ErrorTrace error={error} prettify={false} className={style.errorTrace} />
|
||||||
</pre>
|
</pre>
|
||||||
|
@ -163,3 +166,15 @@ export const ErrorMain = memo(({ error, text }: ErrorProps & { text: string }) =
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
ErrorMain.displayName = "ErrorMain"
|
ErrorMain.displayName = "ErrorMain"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ViewNotice} component for rendering {@link ErrorMain}.
|
||||||
|
*/
|
||||||
|
export const ErrorView = memo((props: ErrorProps) => {
|
||||||
|
return (
|
||||||
|
<ViewNotice
|
||||||
|
notice={<ErrorMain {...props} />}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
|
@ -3,7 +3,7 @@ import '@fortawesome/fontawesome-svg-core/styles.css'
|
||||||
import { AppProps } from 'next/app'
|
import { AppProps } from 'next/app'
|
||||||
import { appWithTranslation, useTranslation } from 'next-i18next'
|
import { appWithTranslation, useTranslation } from 'next-i18next'
|
||||||
import { AxiosSWRFetcherProvider } from '../components/auth/requests'
|
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 { AuthContextProvider } from '../components/auth/provider'
|
||||||
import { PostcardRenderer } from '../components/postcard/renderer'
|
import { PostcardRenderer } from '../components/postcard/renderer'
|
||||||
import { config as fontAwesomeConfig } from '@fortawesome/fontawesome-svg-core'
|
import { config as fontAwesomeConfig } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
@ -19,22 +19,22 @@ const App = ({ Component, pageProps }: AppProps): JSX.Element => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ErrorBoundaryPage text={t("genericError")}>
|
<ErrorBoundaryView text={t("genericError")}>
|
||||||
<AxiosSWRFetcherProvider>
|
<AxiosSWRFetcherProvider>
|
||||||
<PostcardContextProvider defaultPostcard={defaultPostcard}>
|
<PostcardContextProvider defaultPostcard={defaultPostcard}>
|
||||||
<AuthContextProvider storageKey="auth">
|
<AuthContextProvider storageKey="auth">
|
||||||
<AxiosSWRFetcherProvider>
|
<AxiosSWRFetcherProvider>
|
||||||
<PostcardRenderer />
|
<PostcardRenderer />
|
||||||
<ErrorBoundaryPage text={t("genericError")}>
|
<ErrorBoundaryView text={t("genericError")}>
|
||||||
<LoadingBoundaryPage>
|
<LoadingBoundaryPage>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</LoadingBoundaryPage>
|
</LoadingBoundaryPage>
|
||||||
</ErrorBoundaryPage>
|
</ErrorBoundaryView>
|
||||||
</AxiosSWRFetcherProvider>
|
</AxiosSWRFetcherProvider>
|
||||||
</AuthContextProvider>
|
</AuthContextProvider>
|
||||||
</PostcardContextProvider>
|
</PostcardContextProvider>
|
||||||
</AxiosSWRFetcherProvider>
|
</AxiosSWRFetcherProvider>
|
||||||
</ErrorBoundaryPage>
|
</ErrorBoundaryView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue