From e1795e4af97aa8ca59fec531c6d691e9c2d6c613 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Fri, 6 Aug 2021 13:45:44 +0400 Subject: [PATCH 1/4] Site Editor: Add error boundary --- .../edit-site/src/components/editor/index.js | 163 +++++++++--------- .../src/components/error-boundary/index.js | 64 +++++++ packages/edit-site/src/index.js | 26 ++- 3 files changed, 170 insertions(+), 83 deletions(-) create mode 100644 packages/edit-site/src/components/error-boundary/index.js diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 64ebff5a9612d..64b568f41f000 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -39,6 +39,7 @@ import NavigationSidebar from '../navigation-sidebar'; import URLQueryController from '../url-query-controller'; import InserterSidebar from '../secondary-sidebar/inserter-sidebar'; import ListViewSidebar from '../secondary-sidebar/list-view-sidebar'; +import ErrorBoundary from '../error-boundary'; import { store as editSiteStore } from '../../store'; const interfaceLabels = { @@ -46,7 +47,7 @@ const interfaceLabels = { drawer: __( 'Navigation Sidebar' ), }; -function Editor( { initialSettings } ) { +function Editor( { initialSettings, onError } ) { const { isInserterOpen, isListViewOpen, @@ -178,9 +179,6 @@ function Editor( { initialSettings } ) { return ( <> - - - - - - } - secondarySidebar={ secondarySidebar() } - sidebar={ - sidebarIsOpened && ( - - ) - } - header={ -
- } - notices={ } - content={ - <> - - { template && ( - - ) } - { templateResolved && - ! template && - settings?.siteUrl && - entityId && ( - + + + + + + } + secondarySidebar={ secondarySidebar() } + sidebar={ + sidebarIsOpened && ( + + ) + } + header={ +
+ } + notices={ } + content={ + <> + + { template && ( + - { __( - "You attempted to edit an item that doesn't exist. Perhaps it was deleted?" - ) } - + /> ) } - - - } - actions={ - <> - { isEntitiesSavedStatesOpen ? ( - - ) : ( -
- -
- ) } - - } - footer={ } - /> - - + /> + ) : ( +
+ +
+ ) } + + } + footer={ } + /> + + + diff --git a/packages/edit-site/src/components/error-boundary/index.js b/packages/edit-site/src/components/error-boundary/index.js new file mode 100644 index 0000000000000..e425df492405f --- /dev/null +++ b/packages/edit-site/src/components/error-boundary/index.js @@ -0,0 +1,64 @@ +/** + * WordPress dependencies + */ +import { Component } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { Button } from '@wordpress/components'; +import { Warning } from '@wordpress/block-editor'; +import { useCopyToClipboard } from '@wordpress/compose'; + +function CopyButton( { text, children } ) { + const ref = useCopyToClipboard( text ); + return ( + + ); +} + +export default class ErrorBoundary extends Component { + constructor() { + super( ...arguments ); + + this.reboot = this.reboot.bind( this ); + + this.state = { + error: null, + }; + } + + static getDerivedStateFromError( error ) { + return { error }; + } + + reboot() { + this.props.onError(); + } + + render() { + const { error } = this.state; + if ( ! error ) { + return this.props.children; + } + + return ( + + { __( 'Attempt Recovery' ) } + , + + { __( 'Copy Error' ) } + , + ] } + > + { __( 'The editor has encountered an unexpected error.' ) } + + ); + } +} diff --git a/packages/edit-site/src/index.js b/packages/edit-site/src/index.js index fe42ad69af26c..8a33589ad9f60 100644 --- a/packages/edit-site/src/index.js +++ b/packages/edit-site/src/index.js @@ -5,7 +5,7 @@ import { registerCoreBlocks, __experimentalRegisterExperimentalCoreBlocks, } from '@wordpress/block-library'; -import { render } from '@wordpress/element'; +import { render, unmountComponentAtNode } from '@wordpress/element'; import { __experimentalFetchLinkSuggestions as fetchLinkSuggestions } from '@wordpress/core-data'; /** @@ -16,6 +16,23 @@ import './hooks'; import './store'; import Editor from './components/editor'; +/** + * Reinitializes the editor after the user chooses to reboot the editor after + * an unhandled error occurs, replacing previously mounted editor element using + * an initial state from prior to the crash. + * + * @param {Element} target DOM node in which editor is rendered. + * @param {?Object} settings Editor settings object. + */ +export function reinitializeEditor( target, settings ) { + unmountComponentAtNode( target ); + const reboot = reinitializeEditor.bind( null, target, settings ); + render( + , + target + ); +} + /** * Initializes the site editor screen. * @@ -27,6 +44,9 @@ export function initialize( id, settings ) { fetchLinkSuggestions( search, searchOptions, settings ); settings.__experimentalSpotlightEntityBlocks = [ 'core/template-part' ]; + const target = document.getElementById( id ); + const reboot = reinitializeEditor.bind( null, target, settings ); + registerCoreBlocks(); if ( process.env.GUTENBERG_PHASE === 2 ) { __experimentalRegisterExperimentalCoreBlocks( { @@ -35,8 +55,8 @@ export function initialize( id, settings ) { } render( - , - document.getElementById( id ) + , + target ); } From bd42ec677e99ee33905382701189b1b5768a75a7 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Mon, 9 Aug 2021 08:47:47 +0400 Subject: [PATCH 2/4] Try componentDidCatch --- packages/edit-site/src/components/error-boundary/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/error-boundary/index.js b/packages/edit-site/src/components/error-boundary/index.js index e425df492405f..fc69405c3372b 100644 --- a/packages/edit-site/src/components/error-boundary/index.js +++ b/packages/edit-site/src/components/error-boundary/index.js @@ -27,8 +27,8 @@ export default class ErrorBoundary extends Component { }; } - static getDerivedStateFromError( error ) { - return { error }; + componentDidCatch( error ) { + this.setState( { error } ); } reboot() { From e564b5f3e27141462b23ccd1ec8efc0dd2c51c15 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Mon, 9 Aug 2021 16:19:01 +0400 Subject: [PATCH 3/4] Revert "Try componentDidCatch" This reverts commit bd42ec677e99ee33905382701189b1b5768a75a7. --- packages/edit-site/src/components/error-boundary/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/edit-site/src/components/error-boundary/index.js b/packages/edit-site/src/components/error-boundary/index.js index fc69405c3372b..e425df492405f 100644 --- a/packages/edit-site/src/components/error-boundary/index.js +++ b/packages/edit-site/src/components/error-boundary/index.js @@ -27,8 +27,8 @@ export default class ErrorBoundary extends Component { }; } - componentDidCatch( error ) { - this.setState( { error } ); + static getDerivedStateFromError( error ) { + return { error }; } reboot() { From 3bf02460f7ee6abd45eb86e277326dde2bef4a22 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Mon, 9 Aug 2021 16:51:08 +0400 Subject: [PATCH 4/4] Move URLQueryController component back to top level --- packages/edit-site/src/components/editor/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 64b568f41f000..c9225340907ba 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -179,6 +179,7 @@ function Editor( { initialSettings, onError } ) { return ( <> + -