mirror of
https://github.com/facebook/react.git
synced 2026-02-25 22:35:12 +00:00
115 lines
2.9 KiB
JavaScript
115 lines
2.9 KiB
JavaScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
*/
|
|
|
|
import React, {Component} from 'react';
|
|
import styles from './ErrorBoundary.css';
|
|
|
|
type Props = {|
|
|
children: React$Node,
|
|
|};
|
|
|
|
type State = {|
|
|
callStack: string | null,
|
|
componentStack: string | null,
|
|
errorMessage: string | null,
|
|
hasError: boolean,
|
|
|};
|
|
|
|
export default class ErrorBoundary extends Component<Props, State> {
|
|
state: State = {
|
|
callStack: null,
|
|
componentStack: null,
|
|
errorMessage: null,
|
|
hasError: false,
|
|
};
|
|
|
|
componentDidCatch(error: any, {componentStack}: any) {
|
|
const errorMessage =
|
|
typeof error === 'object' && error.hasOwnProperty('message')
|
|
? error.message
|
|
: error;
|
|
|
|
const callStack =
|
|
typeof error === 'object' && error.hasOwnProperty('stack')
|
|
? error.stack
|
|
.split('\n')
|
|
.slice(1)
|
|
.join('\n')
|
|
: null;
|
|
|
|
this.setState({
|
|
callStack,
|
|
componentStack,
|
|
errorMessage,
|
|
hasError: true,
|
|
});
|
|
}
|
|
|
|
render() {
|
|
const {children} = this.props;
|
|
const {callStack, componentStack, errorMessage, hasError} = this.state;
|
|
|
|
let bugURL = process.env.GITHUB_URL;
|
|
if (bugURL) {
|
|
const title = `Error: "${errorMessage || ''}"`;
|
|
const label = 'Component: Developer Tools';
|
|
|
|
let body = 'Describe what you were doing when the bug occurred:';
|
|
body += '\n1. ';
|
|
body += '\n2. ';
|
|
body += '\n3. ';
|
|
body += '\n\n---------------------------------------------';
|
|
body += '\nPlease do not remove the text below this line';
|
|
body += '\n---------------------------------------------';
|
|
body += `\n\nDevTools version: ${process.env.DEVTOOLS_VERSION || ''}`;
|
|
if (callStack) {
|
|
body += `\n\nCall stack: ${callStack.trim()}`;
|
|
}
|
|
if (componentStack) {
|
|
body += `\n\nComponent stack: ${componentStack.trim()}`;
|
|
}
|
|
|
|
bugURL += `/issues/new?labels=${encodeURI(label)}&title=${encodeURI(
|
|
title,
|
|
)}&body=${encodeURI(body)}`;
|
|
}
|
|
|
|
if (hasError) {
|
|
return (
|
|
<div className={styles.ErrorBoundary}>
|
|
<div className={styles.Header}>
|
|
An error was thrown: "{errorMessage}"
|
|
</div>
|
|
{bugURL && (
|
|
<a
|
|
href={bugURL}
|
|
rel="noopener noreferrer"
|
|
target="_blank"
|
|
title="Report bug">
|
|
Report this issue
|
|
</a>
|
|
)}
|
|
{!!callStack && (
|
|
<div className={styles.Stack}>
|
|
The error was thrown {callStack.trim()}
|
|
</div>
|
|
)}
|
|
{!!componentStack && (
|
|
<div className={styles.Stack}>
|
|
The error occurred {componentStack.trim()}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return children;
|
|
}
|
|
}
|