Wrap activity panels in error boundary (#48415)

* Fix review error type

* Add changelog

* Rename global error-boundary class to avoid conflict

* Rename global error-boundary class to avoid conflict

* Wrap panels in error boundary

* Remove console

* Reformat

* Fix test

* Fix test

* Add changelog
This commit is contained in:
Chi-Hsuan Huang 2024-06-17 13:05:11 +08:00 committed by GitHub
parent 1e92b0efaf
commit 4162a6ef89
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 85 additions and 87 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fix review store error type

View File

@ -27,7 +27,7 @@ export function setReview( reviewId: number, reviewData: ReviewObject ) {
};
}
export function setError( query: ReviewsQueryParams | string, error: unknown ) {
export function setError( query: string, error: unknown ) {
return {
type: TYPES.SET_ERROR,
query,

View File

@ -59,7 +59,7 @@ const reducer: Reducer< ReviewsState, Action > = (
...state,
errors: {
...state.errors,
[ JSON.stringify( action.query ) ]: action.error,
[ action.query ]: action.error,
},
};
case TYPES.SET_REVIEW_IS_UPDATING:

View File

@ -88,7 +88,7 @@ describe( 'reviews reducer', () => {
} );
it( 'should handle SET_ERROR', () => {
const query = { status: 'spam' as const };
const query = JSON.stringify( { status: 'spam' as const } );
const error = 'Baaam!';
const state = reducer( defaultState, {
type: TYPES.SET_ERROR,
@ -96,8 +96,7 @@ describe( 'reviews reducer', () => {
error,
} );
const stringifiedQuery = JSON.stringify( query );
expect( state.errors[ stringifiedQuery ] ).toBe( error );
expect( state.errors[ query ] ).toBe( error );
} );
it( 'should handle SET_REVIEW', () => {

View File

@ -53,17 +53,17 @@ export class ErrorBoundary extends Component<
render() {
if ( this.state.hasError ) {
return (
<div className="woocommerce-error-boundary">
<h1 className="woocommerce-error-boundary__heading">
<div className="woocommerce-global-error-boundary">
<h1 className="woocommerce-global-error-boundary__heading">
{ __( 'Oops, something went wrong', 'woocommerce' ) }
</h1>
<p className="woocommerce-error-boundary__subheading">
<p className="woocommerce-global-error-boundary__subheading">
{ __(
"We're sorry for the inconvenience. Please try reloading the page, or you can get support from the community forums.",
'woocommerce'
) }
</p>
<div className="woocommerce-error-boundary__actions">
<div className="woocommerce-global-error-boundary__actions">
<Button
variant="secondary"
onClick={ this.handleOpenSupport }
@ -77,12 +77,12 @@ export class ErrorBoundary extends Component<
{ __( 'Reload Page', 'woocommerce' ) }
</Button>
</div>
<details className="woocommerce-error-boundary__details">
<details className="woocommerce-global-error-boundary__details">
<summary>
{ __( 'Click for error details', 'woocommerce' ) }
</summary>
<div className="woocommerce-error-boundary__details-content">
<strong className="woocommerce-error-boundary__error">
<div className="woocommerce-global-error-boundary__details-content">
<strong className="woocommerce-global-error-boundary__error">
{ this.state.error &&
this.state.error.toString() }
</strong>

View File

@ -1,11 +1,11 @@
.woocommerce-error-boundary {
.woocommerce-global-error-boundary {
min-height: 100vh;
display: flex;
flex-direction: column;
padding: 70px 20px 0;
box-sizing: border-box;
.woocommerce-error-boundary__heading {
.woocommerce-global-error-boundary__heading {
display: flex;
flex-direction: column;
justify-content: center;
@ -18,11 +18,11 @@
text-align: center;
}
.woocommerce-error-boundary__subheading {
.woocommerce-global-error-boundary__subheading {
text-align: center;
}
.woocommerce-error-boundary__actions {
.woocommerce-global-error-boundary__actions {
display: flex;
justify-content: center;
margin-top: 48px;
@ -32,7 +32,7 @@
}
}
.woocommerce-error-boundary__details {
.woocommerce-global-error-boundary__details {
white-space: pre-wrap;
text-align: left;
margin: 32px auto;
@ -46,7 +46,7 @@
text-align: center;
}
.woocommerce-error-boundary__details-content {
.woocommerce-global-error-boundary__details-content {
padding: 16px 24px;
}

View File

@ -333,25 +333,8 @@ function OrdersPanel( { unreadOrdersCount, orderStatuses } ) {
);
}
const title = __(
'There was an error getting your orders. Please try again.',
'woocommerce'
);
const actionLabel = __( 'Reload', 'woocommerce' );
const actionCallback = () => {
// @todo Add tracking for how often an error is displayed, and the reload action is clicked.
window.location.reload();
};
return (
<>
<EmptyContent
title={ title }
actionLabel={ actionLabel }
actionURL={ null }
actionCallback={ actionCallback }
/>
</>
throw new Error(
'Failed to load orders, raise error to trigger ErrorBoundary'
);
}
const customerList = customerItems

View File

@ -2,6 +2,7 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { __experimentalErrorBoundary as ErrorBoundary } from '@woocommerce/components';
/**
* Internal dependencies
@ -33,10 +34,23 @@ export function getAllPanels( {
id: 'orders-panel',
initialOpen: false,
panel: (
<OrdersPanel
unreadOrdersCount={ unreadOrdersCount }
orderStatuses={ orderStatuses }
/>
<ErrorBoundary
errorMessage={
<>
{ __(
'There was an error getting your orders.',
'woocommerce'
) }
<br />
{ __( 'Please try again.', 'woocommerce' ) }
</>
}
>
<OrdersPanel
unreadOrdersCount={ unreadOrdersCount }
orderStatuses={ orderStatuses }
/>
</ErrorBoundary>
),
title: __( 'Orders', 'woocommerce' ),
},
@ -49,9 +63,22 @@ export function getAllPanels( {
initialOpen: false,
collapsible: lowStockProductsCount !== 0,
panel: (
<StockPanel
lowStockProductsCount={ lowStockProductsCount }
/>
<ErrorBoundary
errorMessage={
<>
{ __(
'There was an error getting your low stock products.',
'woocommerce'
) }
<br />
{ __( 'Please try again.', 'woocommerce' ) }
</>
}
>
<StockPanel
lowStockProductsCount={ lowStockProductsCount }
/>
</ErrorBoundary>
),
title: __( 'Stock', 'woocommerce' ),
},
@ -64,9 +91,22 @@ export function getAllPanels( {
initialOpen: false,
collapsible: unapprovedReviewsCount !== 0,
panel: (
<ReviewsPanel
hasUnapprovedReviews={ unapprovedReviewsCount > 0 }
/>
<ErrorBoundary
errorMessage={
<>
{ __(
'There was an error getting your reviews.',
'woocommerce'
) }
<br />
{ __( 'Please try again.', 'woocommerce' ) }
</>
}
>
<ReviewsPanel
hasUnapprovedReviews={ unapprovedReviewsCount > 0 }
/>
</ErrorBoundary>
),
title: __( 'Reviews', 'woocommerce' ),
},

View File

@ -12,7 +12,6 @@ import StarIcon from 'gridicons/dist/star';
import StarOutlineIcon from 'gridicons/dist/star-outline';
import interpolateComponents from '@automattic/interpolate-components';
import {
EmptyContent,
Link,
ReviewRating,
ProductImage,
@ -307,25 +306,8 @@ class ReviewsPanel extends Component {
const { isRequesting, isError, reviews } = this.props;
if ( isError ) {
const title = __(
'There was an error getting your reviews. Please try again.',
'woocommerce'
);
const actionLabel = __( 'Reload', 'woocommerce' );
const actionCallback = () => {
// @todo Add tracking for how often an error is displayed, and the reload action is clicked.
window.location.reload();
};
return (
<Fragment>
<EmptyContent
title={ title }
actionLabel={ actionLabel }
actionURL={ null }
actionCallback={ actionCallback }
/>
</Fragment>
throw new Error(
'Failed to load reviews, Raise error to trigger ErrorBoundary'
);
}

View File

@ -1,12 +1,11 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { withDispatch, withSelect } from '@wordpress/data';
import PropTypes from 'prop-types';
import { EmptyContent, Section } from '@woocommerce/components';
import { Section } from '@woocommerce/components';
import { ITEMS_STORE_NAME } from '@woocommerce/data';
/**
@ -77,23 +76,8 @@ export class StockPanel extends Component {
this.props;
if ( isError ) {
const title = __(
'There was an error getting your low stock products. Please try again.',
'woocommerce'
);
const actionLabel = __( 'Reload', 'woocommerce' );
const actionCallback = () => {
// @todo Add tracking for how often an error is displayed, and the reload action is clicked.
window.location.reload();
};
return (
<EmptyContent
title={ title }
actionLabel={ actionLabel }
actionURL={ null }
actionCallback={ actionCallback }
/>
throw new Error(
'Failed to load low stock products, Raise error to trigger ErrorBoundary'
);
}

View File

@ -125,7 +125,9 @@
}
.wp-toolbar .is-wp-toolbar-disabled,
.wp-toolbar:has(> .woocommerce-admin-full-screen .woocommerce-error-boundary) {
.wp-toolbar:has(
> .woocommerce-admin-full-screen .woocommerce-global-error-boundary
) {
margin-top: -$adminbar-height;
@include breakpoint("<600px") {
margin-top: -$adminbar-height-mobile;

View File

@ -0,0 +1,4 @@
Significance: patch
Type: update
Wrap activity panels in error boundary