diff --git a/src/chrome/ShareSheet.js b/src/chrome/ShareSheet.js index b1a318a54..25c582980 100644 --- a/src/chrome/ShareSheet.js +++ b/src/chrome/ShareSheet.js @@ -22,6 +22,7 @@ import {shareFlipperData} from '../fb-stubs/user'; import {exportStore, EXPORT_FLIPPER_TRACE_EVENT} from '../utils/exportData.js'; import PropTypes from 'prop-types'; import {clipboard} from 'electron'; +import ShareSheetErrorList from './ShareSheetErrorList.js'; import {reportPlatformFailures} from '../utils/metrics'; // $FlowFixMe: Missing type defs for node built-in. import {performance} from 'perf_hooks'; @@ -42,36 +43,27 @@ const Uploading = styled(Text)({ marginTop: 15, }); -const ErrorMessage = styled(Text)({ - display: 'block', - marginTop: 6, - wordBreak: 'break-all', - whiteSpace: 'pre-line', - lineHeight: 1.35, -}); - const Copy = styled(Input)({ marginRight: 0, marginBottom: 15, }); -const Title = styled(Text)({ - marginBottom: 6, -}); - const InfoText = styled(Text)({ lineHeight: 1.35, marginBottom: 15, }); -const Padder = styled('div')( - ({paddingLeft, paddingRight, paddingBottom, paddingTop}) => ({ - paddingLeft: paddingLeft || 0, - paddingRight: paddingRight || 0, - paddingBottom: paddingBottom || 0, - paddingTop: paddingTop || 0, - }), -); +const Title = styled(Text)({ + marginBottom: 6, +}); + +const ErrorMessage = styled(Text)({ + display: 'block', + marginTop: 6, + wordBreak: 'break-all', + whiteSpace: 'pre-line', + lineHeight: 1.35, +}); type Props = { onHide: () => mixed, @@ -153,20 +145,7 @@ export default class ShareSheet extends Component { data might contain sensitve information like access tokens used in network requests. - {this.state.errorArray.length > 0 && ( - - - - The following errors occurred while exporting your - data - - {this.state.errorArray.map((e: Error) => { - return ( - {e.toString()} - ); - })} - - + )} ) : ( diff --git a/src/chrome/ShareSheetErrorList.js b/src/chrome/ShareSheetErrorList.js new file mode 100644 index 000000000..2c1c39401 --- /dev/null +++ b/src/chrome/ShareSheetErrorList.js @@ -0,0 +1,69 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {PureComponent, FlexColumn, Text, styled} from 'flipper'; + +type Props = {| + errors: Array, +|}; + +const ErrorMessage = styled(Text)({ + display: 'block', + marginTop: 6, + wordBreak: 'break-all', + whiteSpace: 'pre-line', + lineHeight: 1.35, +}); + +const Padder = styled('div')( + ({paddingLeft, paddingRight, paddingBottom, paddingTop}) => ({ + paddingLeft: paddingLeft || 0, + paddingRight: paddingRight || 0, + paddingBottom: paddingBottom || 0, + paddingTop: paddingTop || 0, + }), +); + +const Title = styled(Text)({ + marginBottom: 6, +}); + +export function formatError(e: Error): string { + const estr = e.toString(); + + if (estr === '[object Object]') { + try { + return JSON.stringify(e); + } catch (e) { + return ''; + } + } + + return estr; +} + +export default class Popover extends PureComponent { + render() { + if (this.props.errors.length === 0) { + return null; + } + return ( + <> + + + + The following errors occurred while exporting your data + + {this.props.errors.map((e: Error) => ( + {formatError(e)} + ))} + + + + ); + } +} diff --git a/src/chrome/ShareSheetExportFile.js b/src/chrome/ShareSheetExportFile.js index 7ec491e2f..40353524b 100644 --- a/src/chrome/ShareSheetExportFile.js +++ b/src/chrome/ShareSheetExportFile.js @@ -24,6 +24,7 @@ import { EXPORT_FLIPPER_TRACE_EVENT, } from '../utils/exportData.js'; import PropTypes from 'prop-types'; +import ShareSheetErrorList from './ShareSheetErrorList.js'; const Container = styled(FlexColumn)({ padding: 20, @@ -57,20 +58,12 @@ const InfoText = styled(Text)({ marginBottom: 15, }); -const Padder = styled('div')( - ({paddingLeft, paddingRight, paddingBottom, paddingTop}) => ({ - paddingLeft: paddingLeft || 0, - paddingRight: paddingRight || 0, - paddingBottom: paddingBottom || 0, - paddingTop: paddingTop || 0, - }), -); - type Props = { onHide: () => mixed, file: ?string, logger: Logger, }; + type State = { errorArray: Array, result: ?{ @@ -128,16 +121,7 @@ export default class ShareSheetExportFile extends Component { might contain sensitive information like access tokens used in network requests. - {this.state.errorArray.length > 0 && ( - - - Errors: - {this.state.errorArray.map((e: Error) => { - return {e.toString()}; - })} - - - )} + diff --git a/src/chrome/__tests__/ShareSheetErrorList.node.js b/src/chrome/__tests__/ShareSheetErrorList.node.js new file mode 100644 index 000000000..1c112bd21 --- /dev/null +++ b/src/chrome/__tests__/ShareSheetErrorList.node.js @@ -0,0 +1,24 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import {formatError} from '../ShareSheetErrorList.js'; + +test('normal error is formatted', () => { + const e = new Error('something went wrong'); + expect(formatError(e)).toEqual('Error: something went wrong'); +}); + +test('objects are formatted', () => { + const e: any = {iam: 'not an error'}; + expect(formatError(e)).toEqual('{"iam":"not an error"}'); +}); + +test('recursive data structures are not formatted', () => { + const e: any = {b: null}; + e.b = e; + expect(formatError(e)).toEqual(''); +});