0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(console): handling cloud errors

This commit is contained in:
Gao Sun 2023-03-02 12:11:08 +08:00
parent 07e04eac55
commit 2a7c623240
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
6 changed files with 41 additions and 20 deletions

View file

@ -17,6 +17,7 @@ import initI18n from '@/i18n/init';
import { adminTenantEndpoint } from './consts';
import { isCloud } from './consts/cloud';
import ErrorBoundary from './containers/ErrorBoundary';
import AppConfirmModalProvider from './contexts/AppConfirmModalProvider';
import AppEndpointsProvider from './contexts/AppEndpointsProvider';
import TenantsProvider, { TenantsContext } from './contexts/TenantsProvider';
@ -68,9 +69,11 @@ const Content = () => {
const App = () => {
return (
<TenantsProvider>
<Content />
</TenantsProvider>
<ErrorBoundary>
<TenantsProvider>
<Content />
</TenantsProvider>
</ErrorBoundary>
);
};
export default App;

View file

@ -6,8 +6,8 @@ import ErrorDark from '@/assets/images/error-dark.svg';
import Error from '@/assets/images/error.svg';
import KeyboardArrowDown from '@/assets/images/keyboard-arrow-down.svg';
import KeyboardArrowUp from '@/assets/images/keyboard-arrow-up.svg';
import { useTheme } from '@/hooks/use-theme';
import { onKeyDownHandler } from '@/utils/a11y';
import { getThemeFromLocalStorage } from '@/utils/theme';
import * as styles from './index.module.scss';
@ -22,7 +22,7 @@ type Props = {
const AppError = ({ title, errorCode, errorMessage, callStack, children }: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const [isDetailsOpen, setIsDetailsOpen] = useState(false);
const theme = useTheme();
const theme = getThemeFromLocalStorage(); // Should be able to use the component in an offline environment
return (
<div className={styles.container}>

View file

@ -1,12 +1,7 @@
import { AppearanceMode } from '@logto/schemas';
import { trySafe } from '@silverhand/essentials';
import { z } from 'zod';
import IllustrationDark from '@/assets/images/loading-illustration-dark.svg';
import Illustration from '@/assets/images/loading-illustration.svg';
import { Daisy as Spinner } from '@/components/Spinner';
import { themeStorageKey } from '@/consts';
import { getTheme } from '@/utils/theme';
import { getThemeFromLocalStorage } from '@/utils/theme';
import * as styles from './index.module.scss';
@ -14,10 +9,7 @@ import * as styles from './index.module.scss';
* An fullscreen loading component fetches local stored theme without sending request.
*/
export const AppLoadingOffline = () => {
const theme = getTheme(
trySafe(() => z.nativeEnum(AppearanceMode).parse(localStorage.getItem(themeStorageKey))) ??
AppearanceMode.SyncWithSystem
);
const theme = getThemeFromLocalStorage();
return (
<div className={styles.container}>

View file

@ -16,10 +16,8 @@ type State = {
};
class ErrorBoundary extends Component<Props, State> {
static getDerivedStateFromError(error: Error) {
const errorMessage = conditional(
typeof error === 'object' && typeof error.message === 'string' && error.message
);
static getDerivedStateFromError(error: Error): State {
const errorMessage = String(error);
const callStack = conditional(
typeof error === 'object' &&
@ -36,6 +34,24 @@ class ErrorBoundary extends Component<Props, State> {
hasError: false,
};
promiseRejectionHandler(error: unknown) {
this.setState(
ErrorBoundary.getDerivedStateFromError(
error instanceof Error ? error : new Error(String(error))
)
);
}
componentDidMount(): void {
window.addEventListener('unhandledrejection', (event) => {
this.promiseRejectionHandler(event.reason);
});
}
componentWillUnmount(): void {
window.removeEventListener('unhandledrejection', this.promiseRejectionHandler);
}
render() {
const { children } = this.props;
const { callStack, errorMessage, hasError } = this.state;

View file

@ -4,7 +4,7 @@ import useApi, { RequestError } from './use-api';
import useSwrFetcher from './use-swr-fetcher';
const useSwrOptions = (): SWRConfiguration => {
const api = useApi({ hideErrorToast: true });
const api = useApi();
const fetcher = useSwrFetcher(api);
return {

View file

@ -1,4 +1,8 @@
import { AppearanceMode } from '@logto/schemas';
import { trySafe } from '@silverhand/essentials';
import { z } from 'zod';
import { themeStorageKey } from '@/consts';
export const getTheme = (appearanceMode: AppearanceMode) => {
if (appearanceMode !== AppearanceMode.SyncWithSystem) {
@ -10,3 +14,9 @@ export const getTheme = (appearanceMode: AppearanceMode) => {
return theme;
};
export const getThemeFromLocalStorage = () =>
getTheme(
trySafe(() => z.nativeEnum(AppearanceMode).parse(localStorage.getItem(themeStorageKey))) ??
AppearanceMode.SyncWithSystem
);