/** * 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 { 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 (
An error was thrown: "{errorMessage}"
{bugURL && ( Report this issue )} {!!callStack && (
The error was thrown {callStack.trim()}
)} {!!componentStack && (
The error occurred {componentStack.trim()}
)}
); } return children; } }