diff --git a/packages/react-error-overlay/package.json b/packages/react-error-overlay/package.json index b3b9365aeb3a025c1c2b4c916e2562c5f0adc642..78e822a3ee575fdd1ffdc52077a2d33d34b5314a 100644 --- a/packages/react-error-overlay/package.json +++ b/packages/react-error-overlay/package.json @@ -51,7 +51,7 @@ "eslint-plugin-import": "2.7.0", "eslint-plugin-jsx-a11y": "5.1.1", "eslint-plugin-react": "7.1.0", - "flow-bin": "0.52.0", + "flow-bin": "^0.54.0", "jest": "20.0.4", "jest-fetch-mock": "1.2.1" }, diff --git a/packages/react-error-overlay/src/__tests__/__snapshots__/unmapper.js.snap b/packages/react-error-overlay/src/__tests__/__snapshots__/unmapper.js.snap index 18da4f2e7d8b5997f8b1b574b436de545f21758d..102c95e0003208cb78922257dcd973ab8b8cd4ca 100644 --- a/packages/react-error-overlay/src/__tests__/__snapshots__/unmapper.js.snap +++ b/packages/react-error-overlay/src/__tests__/__snapshots__/unmapper.js.snap @@ -46,37 +46,44 @@ Array [ ], "_scriptCode": Array [ ScriptLine { - "content": " },", + "content": " }, +", "highlight": false, "lineNumber": 41463, }, ScriptLine { - "content": " [1, 2].map(function (v) {", + "content": " [1, 2].map(function (v) { +", "highlight": false, "lineNumber": 41464, }, ScriptLine { - "content": " return _react2.default.createElement(", + "content": " return _react2.default.createElement( +", "highlight": false, "lineNumber": 41465, }, ScriptLine { - "content": " 'div',", + "content": " 'div', +", "highlight": true, "lineNumber": 41466, }, ScriptLine { - "content": " {", + "content": " { +", "highlight": false, "lineNumber": 41467, }, ScriptLine { - "content": " __source: {", + "content": " __source: { +", "highlight": false, "lineNumber": 41468, }, ScriptLine { - "content": " fileName: _jsxFileName,", + "content": " fileName: _jsxFileName, +", "highlight": false, "lineNumber": 41469, }, diff --git a/packages/react-error-overlay/src/components/Collapsible.js b/packages/react-error-overlay/src/components/Collapsible.js index 92f1de4295c6b4ddbfa51f164aa3af31c9796ba4..c59919f5352a421198395146c826518017beddc5 100644 --- a/packages/react-error-overlay/src/components/Collapsible.js +++ b/packages/react-error-overlay/src/components/Collapsible.js @@ -9,6 +9,7 @@ /* @flow */ import React, { Component } from 'react'; +import type { Element } from 'react'; import { black } from '../styles'; const _collapsibleStyle = { @@ -35,7 +36,15 @@ const collapsibleExpandedStyle = { marginBottom: '0.6em', }; -class Collapsible extends Component { +type Props = {| + children: Element<any>[] +|}; + +type State = {| + collapsed: boolean +|}; + +class Collapsible extends Component<Props, State> { state = { collapsed: true, }; diff --git a/packages/react-error-overlay/src/components/ErrorOverlay.js b/packages/react-error-overlay/src/components/ErrorOverlay.js index 446105dad2e6decec61bc08e86b7c5a2e41a02f0..148476a3055a9c9b225ce505692eef99b774594b 100644 --- a/packages/react-error-overlay/src/components/ErrorOverlay.js +++ b/packages/react-error-overlay/src/components/ErrorOverlay.js @@ -9,6 +9,7 @@ /* @flow */ import React, { Component } from 'react'; +import type { Node } from 'react'; import { black } from '../styles'; const overlayStyle = { @@ -31,10 +32,19 @@ const overlayStyle = { color: black, }; -class ErrorOverlay extends Component { +type Props = {| + children: Node, + shortcutHandler?: (eventKey: string) => void +|}; + +type State = {| + collapsed: boolean +|}; + +class ErrorOverlay extends Component<Props, State> { iframeWindow: window = null; - getIframeWindow = (element: HTMLDivElement) => { + getIframeWindow = (element: ?HTMLDivElement) => { if (element) { const document = element.ownerDocument; this.iframeWindow = document.defaultView; diff --git a/packages/react-error-overlay/src/containers/CompileErrorContainer.js b/packages/react-error-overlay/src/containers/CompileErrorContainer.js index a3e89fe591d3087fc971b645a4edcc20813bdc23..2995ce61366c04a86009a2cf94e1eba36ebf407c 100644 --- a/packages/react-error-overlay/src/containers/CompileErrorContainer.js +++ b/packages/react-error-overlay/src/containers/CompileErrorContainer.js @@ -15,7 +15,11 @@ import Header from '../components/Header'; import CodeBlock from '../components/CodeBlock'; import generateAnsiHTML from '../utils/generateAnsiHTML'; -class CompileErrorContainer extends PureComponent { +type Props = {| + error: string +|}; + +class CompileErrorContainer extends PureComponent<Props, void> { render() { const { error } = this.props; return ( diff --git a/packages/react-error-overlay/src/containers/RuntimeError.js b/packages/react-error-overlay/src/containers/RuntimeError.js index c64824137d27846ad910fb26d1a694d91d5e8d2e..fe99f40a70a081c032df4618c9e61b0171ecdabe 100644 --- a/packages/react-error-overlay/src/containers/RuntimeError.js +++ b/packages/react-error-overlay/src/containers/RuntimeError.js @@ -65,4 +65,5 @@ function RuntimeError({ errorRecord, launchEditorEndpoint }: Props) { ); } +export type { ErrorRecord }; export default RuntimeError; diff --git a/packages/react-error-overlay/src/containers/RuntimeErrorContainer.js b/packages/react-error-overlay/src/containers/RuntimeErrorContainer.js index 9c41aa381091c9869681f6086518516c8bc31478..e1a3a033b59615634e676678d9c80a90c9c007d5 100644 --- a/packages/react-error-overlay/src/containers/RuntimeErrorContainer.js +++ b/packages/react-error-overlay/src/containers/RuntimeErrorContainer.js @@ -14,8 +14,19 @@ import CloseButton from '../components/CloseButton'; import NavigationBar from '../components/NavigationBar'; import RuntimeError from './RuntimeError'; import Footer from '../components/Footer'; +import type { ErrorRecord } from './RuntimeError'; -class RuntimeErrorContainer extends PureComponent { +type Props = {| + errorRecords: ErrorRecord[], + close: () => void, + launchEditorEndpoint: ?string +|}; + +type State = {| + currentIndex: number +|}; + +class RuntimeErrorContainer extends PureComponent<Props, State> { state = { currentIndex: 0, }; diff --git a/packages/react-error-overlay/src/containers/StackFrame.js b/packages/react-error-overlay/src/containers/StackFrame.js index c95ce003f497359d2fa5909d1f1558c435f04f94..6acb0c327ede209a181dad19cd9d7bc7c73baa3a 100644 --- a/packages/react-error-overlay/src/containers/StackFrame.js +++ b/packages/react-error-overlay/src/containers/StackFrame.js @@ -12,6 +12,7 @@ import React, { Component } from 'react'; import CodeBlock from './StackFrameCodeBlock'; import { getPrettyURL } from '../utils/getPrettyURL'; import { darkGray } from '../styles'; +import type { StackFrame as StackFrameType } from '../utils/stack-frame'; const linkStyle = { fontSize: '0.9em', @@ -43,7 +44,19 @@ const toggleStyle = { lineHeight: '1.5', }; -class StackFrame extends Component { +type Props = {| + frame: StackFrameType, + launchEditorEndpoint: ?string, + contextSize: number, + critical: boolean, + showCode: boolean +|}; + +type State = {| + compiled: boolean +|}; + +class StackFrame extends Component<Props, State> { state = { compiled: false, }; @@ -74,7 +87,7 @@ class StackFrame extends Component { } openInEditor = () => { - if (!this.canOpenInEditor()) { + if (!this.props.launchEditorEndpoint) { return; } const { @@ -90,7 +103,7 @@ class StackFrame extends Component { ).then(() => {}, () => {}); }; - onKeyDown = (e: SyntheticKeyboardEvent) => { + onKeyDown = (e: SyntheticKeyboardEvent<>) => { if (e.key === 'Enter') { this.openInEditor(); } diff --git a/packages/react-error-overlay/src/containers/StackFrameCodeBlock.js b/packages/react-error-overlay/src/containers/StackFrameCodeBlock.js index 2ed685cff49dfcf98b89a9b0d66fc6e4860b0bc4..58a2c0d537cedf8619a16f133b5295cb3a7e44f5 100644 --- a/packages/react-error-overlay/src/containers/StackFrameCodeBlock.js +++ b/packages/react-error-overlay/src/containers/StackFrameCodeBlock.js @@ -21,12 +21,16 @@ import codeFrame from 'babel-code-frame'; type StackFrameCodeBlockPropsType = {| lines: ScriptLine[], lineNum: number, - columnNum: number, + columnNum: ?number, contextSize: number, main: boolean, |}; -function StackFrameCodeBlock(props: StackFrameCodeBlockPropsType) { +// Exact type workaround for spread operator. +// See: https://github.com/facebook/flow/issues/2405 +type Exact<T> = $Shape<T>; + +function StackFrameCodeBlock(props: Exact<StackFrameCodeBlockPropsType>) { const { lines, lineNum, columnNum, contextSize, main } = props; const sourceCode = []; let whiteSpace = Infinity; diff --git a/packages/react-error-overlay/src/containers/StackTrace.js b/packages/react-error-overlay/src/containers/StackTrace.js index 4cb20bce128c1267a76453698706a6e70d26013b..fb086703dd8df5daae6808910fc732302a253e97 100644 --- a/packages/react-error-overlay/src/containers/StackTrace.js +++ b/packages/react-error-overlay/src/containers/StackTrace.js @@ -13,6 +13,7 @@ import StackFrame from './StackFrame'; import Collapsible from '../components/Collapsible'; import { isInternalFile } from '../utils/isInternalFile'; import { isBultinErrorName } from '../utils/isBultinErrorName'; +import type { StackFrame as StackFrameType } from '../utils/stack-frame'; const traceStyle = { fontSize: '1em', @@ -21,7 +22,14 @@ const traceStyle = { overflow: 'auto', }; -class StackTrace extends Component { +type Props = {| + stackFrames: StackFrameType[], + errorName: string, + contextSize: number, + launchEditorEndpoint: ?string, +|}; + +class StackTrace extends Component<Props> { renderFrames() { const { stackFrames, diff --git a/packages/react-error-overlay/src/index.js b/packages/react-error-overlay/src/index.js index 168baa7ef6472698ad881a904637fda6bb0125f8..b33f51e3275d4358754be04c4920725ced26424f 100644 --- a/packages/react-error-overlay/src/index.js +++ b/packages/react-error-overlay/src/index.js @@ -9,6 +9,7 @@ /* @flow */ import React from 'react'; +import type { Element } from 'react'; import ReactDOM from 'react-dom'; import CompileErrorContainer from './containers/CompileErrorContainer'; import RuntimeErrorContainer from './containers/RuntimeErrorContainer'; @@ -21,13 +22,12 @@ import type { ErrorRecord } from './listenToRuntimeErrors'; type RuntimeReportingOptions = {| onError: () => void, launchEditorEndpoint: string, - filename?: string, |}; let iframe: null | HTMLIFrameElement = null; let isLoadingIframe: boolean = false; -let renderedElement: null | React.Element<any> = null; +let renderedElement: null | Element<any> = null; let currentBuildError: null | string = null; let currentRuntimeErrorRecords: Array<ErrorRecord> = []; let currentRuntimeErrorOptions: null | RuntimeReportingOptions = null; @@ -56,7 +56,7 @@ export function startReportingRuntimeErrors(options: RuntimeReportingOptions) { } finally { handleRuntimeError(errorRecord); } - }, options.filename); + }); } function handleRuntimeError(errorRecord) { diff --git a/packages/react-error-overlay/src/listenToRuntimeErrors.js b/packages/react-error-overlay/src/listenToRuntimeErrors.js index 341200afa8bd69a2dd774b7d542c491d96070454..45c43fa5d40d886275aaed5573b2ccc66b34772d 100644 --- a/packages/react-error-overlay/src/listenToRuntimeErrors.js +++ b/packages/react-error-overlay/src/listenToRuntimeErrors.js @@ -39,10 +39,7 @@ export type ErrorRecord = {| stackFrames: StackFrame[], |}; -export function listenToRuntimeErrors( - crash: ErrorRecord => void, - filename: string = '/static/js/bundle.js' -) { +export function listenToRuntimeErrors(crash: ErrorRecord => void) { function crashWithFrames(error: Error, unhandledRejection = false) { getStackFrames(error, unhandledRejection, CONTEXT_SIZE) .then(stackFrames => { @@ -71,7 +68,7 @@ export function listenToRuntimeErrors( { message: data.message, stack: data.stack, - __unmap_source: filename, + __unmap_source: '/static/js/bundle.js', }, false ); diff --git a/packages/react-error-overlay/src/utils/getSourceMap.js b/packages/react-error-overlay/src/utils/getSourceMap.js index 1d8405519bd613640521d601589bed7cda1f0853..a632f3cb3c87e3496fcf28c0054ed332ba992933 100644 --- a/packages/react-error-overlay/src/utils/getSourceMap.js +++ b/packages/react-error-overlay/src/utils/getSourceMap.js @@ -77,7 +77,7 @@ class SourceMap { } } -function extractSourceMapUrl(fileUri: string, fileContents: string) { +function extractSourceMapUrl(fileUri: string, fileContents: string) : Promise<string> { const regex = /\/\/[#@] ?sourceMappingURL=([^\s'"]+)\s*$/gm; let match = null; for (;;) {