mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
Improve error boundary in inspected elements panel (#21531)
Show more info about the error as well as the option to report it to GitHub.
This commit is contained in:
+2
-20
@@ -1,21 +1,3 @@
|
||||
.Error {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
font-size: var(--font-size-sans-large);
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
background-color: var(--color-error-background);
|
||||
color: var(--color-error-text);
|
||||
border: 1px solid var(--color-error-border);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.Message {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.RetryButton {
|
||||
.Wrapper {
|
||||
border-left: 1px solid var(--color-border);
|
||||
}
|
||||
Vendored
+4
-71
@@ -8,13 +8,9 @@
|
||||
*/
|
||||
|
||||
import * as React from 'react';
|
||||
import {Component, useContext} from 'react';
|
||||
import {TreeDispatcherContext} from './TreeContext';
|
||||
import Button from 'react-devtools-shared/src/devtools/views/Button';
|
||||
import ErrorBoundary from '../ErrorBoundary';
|
||||
import styles from './InspectedElementErrorBoundary.css';
|
||||
|
||||
import type {DispatcherContext} from './InspectedElementErrorBoundary.css';
|
||||
|
||||
type WrapperProps = {|
|
||||
children: React$Node,
|
||||
|};
|
||||
@@ -22,72 +18,9 @@ type WrapperProps = {|
|
||||
export default function InspectedElementErrorBoundaryWrapper({
|
||||
children,
|
||||
}: WrapperProps) {
|
||||
const dispatch = useContext(TreeDispatcherContext);
|
||||
|
||||
return (
|
||||
<InspectedElementErrorBoundary children={children} dispatch={dispatch} />
|
||||
<div className={styles.Wrapper}>
|
||||
<ErrorBoundary canDismiss={true}>{children}</ErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type Props = {|
|
||||
children: React$Node,
|
||||
dispatch: DispatcherContext,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
errorMessage: string | null,
|
||||
hasError: boolean,
|
||||
|};
|
||||
|
||||
const InitialState: State = {
|
||||
errorMessage: null,
|
||||
hasError: false,
|
||||
};
|
||||
|
||||
class InspectedElementErrorBoundary extends Component<Props, State> {
|
||||
state: State = InitialState;
|
||||
|
||||
static getDerivedStateFromError(error: any) {
|
||||
const errorMessage =
|
||||
typeof error === 'object' &&
|
||||
error !== null &&
|
||||
error.hasOwnProperty('message')
|
||||
? error.message
|
||||
: error;
|
||||
|
||||
return {
|
||||
errorMessage,
|
||||
hasError: true,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const {children} = this.props;
|
||||
const {errorMessage, hasError} = this.state;
|
||||
|
||||
if (hasError) {
|
||||
return (
|
||||
<div className={styles.Error}>
|
||||
<div className={styles.Message}>{errorMessage || 'Error'}</div>
|
||||
<Button className={styles.RetryButton} onClick={this._retry}>
|
||||
Dismiss
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
_retry = () => {
|
||||
const {dispatch} = this.props;
|
||||
dispatch({
|
||||
type: 'SELECT_ELEMENT_BY_ID',
|
||||
payload: null,
|
||||
});
|
||||
this.setState({
|
||||
errorMessage: null,
|
||||
hasError: false,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
+15
-6
@@ -16,7 +16,8 @@ import SuspendingErrorView from './SuspendingErrorView';
|
||||
|
||||
type Props = {|
|
||||
children: React$Node,
|
||||
store: Store,
|
||||
canDismiss?: boolean,
|
||||
store?: Store,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
@@ -70,18 +71,24 @@ export default class ErrorBoundary extends Component<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.store.addListener('error', this._onStoreError);
|
||||
const {store} = this.props;
|
||||
if (store != null) {
|
||||
store.addListener('error', this._onStoreError);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.store.removeListener('error', this._onStoreError);
|
||||
const {store} = this.props;
|
||||
if (store != null) {
|
||||
store.removeListener('error', this._onStoreError);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {children} = this.props;
|
||||
const {canDismiss: canDismissProp, children} = this.props;
|
||||
const {
|
||||
callStack,
|
||||
canDismiss,
|
||||
canDismiss: canDismissState,
|
||||
componentStack,
|
||||
errorMessage,
|
||||
hasError,
|
||||
@@ -92,7 +99,9 @@ export default class ErrorBoundary extends Component<Props, State> {
|
||||
<ErrorView
|
||||
callStack={callStack}
|
||||
componentStack={componentStack}
|
||||
dismissError={canDismiss ? this._dismissError : null}
|
||||
dismissError={
|
||||
canDismissProp || canDismissState ? this._dismissError : null
|
||||
}
|
||||
errorMessage={errorMessage}>
|
||||
<Suspense fallback={<SearchingGitHubIssues />}>
|
||||
<SuspendingErrorView
|
||||
|
||||
Reference in New Issue
Block a user