Skip to content

Commit

Permalink
CB-4812 fix: infinite loading in error boundary
Browse files Browse the repository at this point in the history
  • Loading branch information
Wroud committed May 23, 2024
1 parent 0957684 commit e819163
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 59 deletions.
27 changes: 11 additions & 16 deletions webapp/packages/core-blocks/src/CommonDialog/DialogsPortal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,7 @@ export const DialogsPortal = observer(function DialogsPortal() {
<Loader className={s(styles, { loader: true })} suspense>
<div className={s(styles, { innerBox: true })}>
{commonDialogService.dialogs.map((dialog, i, arr) => (
<ErrorBoundary key={dialog.id} className={s(styles, { error: true })} remount onClose={state.reject}>
<NestedDialog
key={dialog.id}
visible={i === arr.length - 1}
dialog={dialog}
resolveDialog={state.resolve}
rejectDialog={state.reject}
/>
</ErrorBoundary>
<NestedDialog key={dialog.id} visible={i === arr.length - 1} dialog={dialog} resolveDialog={state.resolve} rejectDialog={state.reject} />
))}
</div>
</Loader>
Expand All @@ -112,6 +104,7 @@ interface NestedDialogType {
}

const NestedDialog: React.FC<NestedDialogType> = function NestedDialog({ dialog, resolveDialog, rejectDialog, visible }) {
const styles = useS(style);
const DialogComponent = dialog.component;

const context = useMemo<IDialogContext>(
Expand All @@ -125,13 +118,15 @@ const NestedDialog: React.FC<NestedDialogType> = function NestedDialog({ dialog,

return (
<DialogContext.Provider value={context}>
<DialogComponent
visible={visible}
payload={dialog.payload}
options={dialog.options}
resolveDialog={resolveDialog}
rejectDialog={rejectDialog}
/>
<ErrorBoundary className={s(styles, { error: true })} remount onClose={rejectDialog}>
<DialogComponent
visible={visible}
payload={dialog.payload}
options={dialog.options}
resolveDialog={resolveDialog}
rejectDialog={rejectDialog}
/>
</ErrorBoundary>
</DialogContext.Provider>
);
};
96 changes: 53 additions & 43 deletions webapp/packages/core-blocks/src/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import React, { ErrorInfo } from 'react';
import React, { ErrorInfo, Suspense } from 'react';

import { errorOf, LoadingError } from '@cloudbeaver/core-utils';

Expand Down Expand Up @@ -76,62 +76,72 @@ export class ErrorBoundary extends React.Component<React.PropsWithChildren<Props
if (this.props.simple) {
const stack = errorData.errorInfo?.componentStack || errorData.error.stack;
return (
<div>
<p>Something went wrong.</p>
{onClose && (
<div className={style.action}>
<button type="button" onClick={onClose}>
Close
</button>
</div>
)}
{this.canRefresh && (
<div className={style.action}>
<button type="button" onClick={this.refresh}>
Refresh
</button>
</div>
)}
<Suspense fallback={<>Loading...</>}>
<div>
{errorData.error.toString()}
{stack && <br />}
{stack}
<p>Something went wrong.</p>
{onClose && (
<div className={style.action}>
<button type="button" onClick={onClose}>
Close
</button>
</div>
)}
{this.canRefresh && (
<div className={style.action}>
<button type="button" onClick={this.refresh}>
Refresh
</button>
</div>
)}
<div>
{errorData.error.toString()}
{stack && <br />}
{stack}
</div>
{this.props.fallback}
</div>
{this.props.fallback}
</div>
</Suspense>
);
}

if (root) {
return (
<DisplayError className={className} root={root} error={errorData.error} errorInfo={errorData.errorInfo}>
{onClose && (
<div className={style.action}>
<Button onClick={onClose}>Close</Button>
</div>
)}
{this.canRefresh && (
<div className={style.action}>
<Button onClick={this.refresh}>Refresh</Button>
</div>
)}
</DisplayError>
<Suspense fallback={<>Loading...</>}>
<DisplayError className={className} root={root} error={errorData.error} errorInfo={errorData.errorInfo}>
{onClose && (
<div className={style.action}>
<Button onClick={onClose}>Close</Button>
</div>
)}
{this.canRefresh && (
<div className={style.action}>
<Button onClick={this.refresh}>Refresh</Button>
</div>
)}
</DisplayError>
</Suspense>
);
} else {
return (
<ExceptionMessage
inline={inline}
icon={icon}
className={className}
exception={errorData.error}
onRetry={this.canRefresh ? this.refresh : undefined}
onClose={onClose}
/>
<Suspense fallback={<>Loading...</>}>
<ExceptionMessage
inline={inline}
icon={icon}
className={className}
exception={errorData.error}
onRetry={this.canRefresh ? this.refresh : undefined}
onClose={onClose}
/>
</Suspense>
);
}
}

return <ErrorContext.Provider value={this}>{children}</ErrorContext.Provider>;
return (
<ErrorContext.Provider value={this}>
<Suspense fallback={<>Loading...</>}>{children}</Suspense>
</ErrorContext.Provider>
);
}

private refresh() {
Expand Down

0 comments on commit e819163

Please sign in to comment.