Skip to content

Commit

Permalink
BUGFIX: Primitive Root ErrorBoundary
Browse files Browse the repository at this point in the history
TASK: Fix layout and add copy button

thanks to @jonnitto

TASK: Move buttons together

TASK: Add sparkles to ReloadNeosUiButton

TASK: Remove dep `react-error-boundary`

TASK: More descriptive error in dev context

;)

TASK: Style issues
  • Loading branch information
mhsdesign committed Jun 8, 2023
1 parent e720646 commit 0f34897
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 13 deletions.
Binary file added Resources/Public/Images/neos-logo-enhanced.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
93 changes: 93 additions & 0 deletions packages/neos-ui/src/Containers/ErrorBoundary/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React from 'react';
import styles from './style.module.css';
import {Logo, Button, Icon} from '@neos-project/react-ui-components';

class ErrorBoundary extends React.Component<
{ children: React.ReactNode },
{ error: any }
> {
state = {error: undefined};

static getDerivedStateFromError(error: any) {
return {error};
}

render() {
if (this.state.error !== undefined) {
return <ErrorFallback error={this.state.error} />;
}
return this.props.children;
}
}

const CopyTechnicalDetailsButton = (props: { error: any }) => {
const [hasCopied, setCopied] = React.useState(false);

const copyErrorDetails = () => {
setCopied(true);
const error = props.error as Error;
window.navigator.clipboard.writeText(`Name: ${error.name}\n\nMessage: ${error.message}\n\nStacktrace: ${error.stack}`);
}

if (!window.navigator.clipboard || !(props.error instanceof Error)) {
return null;
}

return <Button onClick={copyErrorDetails} isActive={hasCopied}>{!hasCopied ? 'Copy technical details' : 'Technical details copied'} &nbsp; <Icon icon="copy" size="sm"/></Button>
}

const ReloadNeosUiButton = () => {
const [isReloading, setReload] = React.useState(false);
const reload = () => {
if (isReloading) {
return;
}
setReload(true);
setTimeout(() => {
document.location.reload();
}, 100)
}

return <Button onClick={reload}>Reload Neos UI &nbsp; <Icon icon="redo" size="sm" spin={isReloading}/></Button>;
}

const ErrorFallback = (props: { error: any }) => {
// @ts-ignore
const isDev = window.neos?.systemEnv.startsWith('Development');

return <div className={styles.container}>
<div>
{isDev
? <img style={{height: '48px'}} src="/_Resources/Static/Packages/Neos.Neos.UI/Images/neos-logo-enhanced.gif" title="This... This can't be. We programm without bugs." alt="Neos Logo" />
: <Logo />
}
<h1 className={styles.title}>Sorry, but the Neos UI could not recover from this Error.</h1>
<p>Please reload the application, or contact your system administrator with the given details.</p>

{props.error instanceof Error &&
<>
<p>
Name: {props.error.name || '-'}
</p>
<p>
Message: {props.error.message || '-'}
</p>
<p>Stacktrace:</p>
<pre className={styles.stackTrace}>
<code>
{props.error.stack}
</code>
</pre>
</>
}
<p>For more information about the Error please refer to the JavaScript console.</p>

<div className={styles.buttonGroup}>
<ReloadNeosUiButton />
<CopyTechnicalDetailsButton error={props.error} />
</div>
</div>
</div>
};

export default ErrorBoundary;
31 changes: 31 additions & 0 deletions packages/neos-ui/src/Containers/ErrorBoundary/style.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.container {
width: 100%;
min-height: 100vh;
background-color: #222;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}

.container > * {
flex: 0 1 800px;
margin: var(--spacing-Full);
overflow: auto;
}

.title {
line-height: 1;
}
.stackTrace {
overflow-x: auto;
border-top: 1px solid var(--colors-PrimaryBlue);
border-bottom: 1px solid var(--colors-PrimaryBlue);
padding: var(--spacing-Half) 0;
}

.buttonGroup {
display: flex;
flex-wrap: wrap;
gap: var(--spacing-Half) var(--spacing-Full);
}
29 changes: 16 additions & 13 deletions packages/neos-ui/src/Containers/Root.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Provider} from 'react-redux';
import ErrorBoundary from './ErrorBoundary';
import {DndProvider} from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import style from './style.css';
Expand All @@ -15,19 +16,21 @@ class Root extends PureComponent {
const App = containerRegistry.get('App');

return (
<div className={style.applicationWrapper}>
<Provider store={store}>
<DndProvider backend={HTML5Backend}>
<Neos
globalRegistry={globalRegistry}
configuration={configuration}
routes={routes}
>
<App globalRegistry={globalRegistry} menu={menu}/>
</Neos>
</DndProvider>
</Provider>
</div>
<ErrorBoundary>
<div className={style.applicationWrapper}>
<Provider store={store}>
<DndProvider backend={HTML5Backend}>
<Neos
globalRegistry={globalRegistry}
configuration={configuration}
routes={routes}
>
<App globalRegistry={globalRegistry} menu={menu}/>
</Neos>
</DndProvider>
</Provider>
</div>
</ErrorBoundary>
);
}
}
Expand Down

0 comments on commit 0f34897

Please sign in to comment.