Skip to content

Commit 216efc7

Browse files
committed
Fix decoupling of react-dev-utils and react-error-overlay by moving middleware
1 parent 448b16f commit 216efc7

File tree

10 files changed

+81
-45
lines changed

10 files changed

+81
-45
lines changed

packages/react-dev-utils/errorOverlayMiddleware.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,18 @@
66
* LICENSE file in the root directory of this source tree. An additional grant
77
* of patent rights can be found in the PATENTS file in the same directory.
88
*/
9-
109
'use strict';
1110

12-
module.exports = require('react-error-overlay/middleware');
11+
const launchEditor = require('./launchEditor');
12+
const launchEditorEndpoint = require('./launchEditorEndpoint');
13+
14+
module.exports = function createLaunchEditorMiddleware() {
15+
return function launchEditorMiddleware(req, res, next) {
16+
if (req.url.startsWith(launchEditorEndpoint)) {
17+
launchEditor(req.query.fileName, req.query.lineNumber);
18+
res.end();
19+
} else {
20+
next();
21+
}
22+
};
23+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
'use strict';
10+
11+
// TODO: we might want to make this injectable to support DEV-time non-root URLs.
12+
module.exports = '/__open-stack-frame-in-editor';

packages/react-dev-utils/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"inquirer.js",
2525
"InterpolateHtmlPlugin.js",
2626
"launchEditor.js",
27+
"launchEditorEndpoint.js",
2728
"ModuleScopePlugin.js",
2829
"noopServiceWorkerMiddleware.js",
2930
"openBrowser.js",

packages/react-dev-utils/webpackHotDevClient.js

+10-6
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,22 @@
2121
var SockJS = require('sockjs-client');
2222
var stripAnsi = require('strip-ansi');
2323
var url = require('url');
24+
var launchEditorEndpoint = require('./launchEditorEndpoint');
2425
var formatWebpackMessages = require('./formatWebpackMessages');
2526
var ErrorOverlay = require('react-error-overlay');
2627

27-
ErrorOverlay.startReportingRuntimeErrors(() => {
28-
// TODO: why do we need this?
29-
if (module.hot && typeof module.hot.decline === 'function') {
30-
module.hot.decline();
31-
}
28+
ErrorOverlay.startReportingRuntimeErrors({
29+
launchEditorEndpoint: launchEditorEndpoint,
30+
onError: function() {
31+
// TODO: why do we need this?
32+
if (module.hot && typeof module.hot.decline === 'function') {
33+
module.hot.decline();
34+
}
35+
},
3236
});
3337

3438
if (module.hot && typeof module.hot.dispose === 'function') {
35-
module.hot.dispose(() => {
39+
module.hot.dispose(function() {
3640
// TODO: why do we need this?
3741
ErrorOverlay.stopReportingRuntimeErrors();
3842
});

packages/react-error-overlay/middleware.js

-23
This file was deleted.

packages/react-error-overlay/src/containers/RuntimeError.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ type ErrorRecord = {|
2525
stackFrames: StackFrame[],
2626
|};
2727

28-
function RuntimeError({ errorRecord }: { errorRecord: ErrorRecord }) {
28+
type Props = {|
29+
errorRecord: ErrorRecord,
30+
launchEditorEndpoint: ?string,
31+
|};
32+
33+
function RuntimeError({ errorRecord, launchEditorEndpoint }: Props) {
2934
const { error, unhandledRejection, contextSize, stackFrames } = errorRecord;
3035
const errorName = unhandledRejection
3136
? 'Unhandled Rejection (' + error.name + ')'
@@ -54,6 +59,7 @@ function RuntimeError({ errorRecord }: { errorRecord: ErrorRecord }) {
5459
stackFrames={stackFrames}
5560
errorName={errorName}
5661
contextSize={contextSize}
62+
launchEditorEndpoint={launchEditorEndpoint}
5763
/>
5864
</div>
5965
);

packages/react-error-overlay/src/containers/RuntimeErrorContainer.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ class RuntimeErrorContainer extends PureComponent {
6161
previous={this.previous}
6262
next={this.next}
6363
/>}
64-
<RuntimeError errorRecord={errorRecords[this.state.currentIndex]} />
64+
<RuntimeError
65+
errorRecord={errorRecords[this.state.currentIndex]}
66+
launchEditorEndpoint={this.props.launchEditorEndpoint}
67+
/>
6568
<Footer
6669
line1="This screen is visible only in development. It will not appear if the app crashes in production."
6770
line2="Open your browser’s developer console to further inspect this error."

packages/react-error-overlay/src/containers/StackFrame.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ class StackFrame extends Component {
5555
};
5656

5757
canOpenInEditor() {
58+
if (!this.props.launchEditorEndpoint) {
59+
return;
60+
}
5861
const { _originalFileName: sourceFileName } = this.props.frame;
5962
// Unknown file
6063
if (!sourceFileName) {
@@ -80,7 +83,7 @@ class StackFrame extends Component {
8083
} = this.props.frame;
8184
// Keep this in sync with react-error-overlay/middleware.js
8285
fetch(
83-
'/__open-stack-frame-in-editor?fileName=' +
86+
`${this.props.launchEditorEndpoint}?fileName=` +
8487
window.encodeURIComponent(sourceFileName) +
8588
'&lineNumber=' +
8689
window.encodeURIComponent(sourceLineNumber || 1)

packages/react-error-overlay/src/containers/StackTrace.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ const traceStyle = {
2323

2424
class StackTrace extends Component {
2525
renderFrames() {
26-
const { stackFrames, errorName, contextSize } = this.props;
26+
const {
27+
stackFrames,
28+
errorName,
29+
contextSize,
30+
launchEditorEndpoint,
31+
} = this.props;
2732
const renderedFrames = [];
2833
let hasReachedAppCode = false,
2934
currentBundle = [],
@@ -47,6 +52,7 @@ class StackTrace extends Component {
4752
contextSize={contextSize}
4853
critical={index === 0}
4954
showCode={!shouldCollapse}
55+
launchEditorEndpoint={launchEditorEndpoint}
5056
/>
5157
);
5258
const lastElement = index === stackFrames.length - 1;

packages/react-error-overlay/src/index.js

+23-10
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,18 @@ import { applyStyles } from './utils/dom/css';
1818

1919
import type { ErrorRecord } from './listenToRuntimeErrors';
2020

21+
type RuntimeReportingOptions = {|
22+
onError: () => void,
23+
launchEditorEndpoint: string,
24+
|};
25+
2126
let iframe: null | HTMLIFrameElement = null;
2227
let isLoadingIframe: boolean = false;
2328

2429
let renderedElement: null | React.Element<any> = null;
2530
let currentBuildError: null | string = null;
2631
let currentRuntimeErrorRecords: Array<ErrorRecord> = [];
32+
let currentRuntimeErrorOptions: null | RuntimeReportingOptions = null;
2733
let stopListeningToRuntimeErrors: null | (() => void) = null;
2834

2935
export function reportBuildError(error: string) {
@@ -36,14 +42,15 @@ export function dismissBuildError() {
3642
update();
3743
}
3844

39-
export function startReportingRuntimeErrors(onError?: () => void) {
45+
export function startReportingRuntimeErrors(options: RuntimeReportingOptions) {
4046
if (stopListeningToRuntimeErrors !== null) {
41-
return;
47+
throw new Error('Already listening');
4248
}
49+
currentRuntimeErrorOptions = options;
4350
listenToRuntimeErrors(errorRecord => {
4451
try {
45-
if (typeof onError === 'function') {
46-
onError();
52+
if (typeof options.onError === 'function') {
53+
options.onError.call(null);
4754
}
4855
} finally {
4956
handleRuntimeError(errorRecord);
@@ -62,12 +69,14 @@ function dismissRuntimeErrors() {
6269
}
6370

6471
export function stopReportingRuntimeErrors() {
65-
if (stopListeningToRuntimeErrors !== null) {
66-
try {
67-
stopListeningToRuntimeErrors();
68-
} finally {
69-
stopListeningToRuntimeErrors = null;
70-
}
72+
if (stopListeningToRuntimeErrors === null) {
73+
throw new Error('Not currently listening');
74+
}
75+
currentRuntimeErrorOptions = null;
76+
try {
77+
stopListeningToRuntimeErrors();
78+
} finally {
79+
stopListeningToRuntimeErrors = null;
7180
}
7281
}
7382

@@ -114,10 +123,14 @@ function render() {
114123
return <CompileErrorContainer error={currentBuildError} />;
115124
}
116125
if (currentRuntimeErrorRecords.length > 0) {
126+
if (!currentRuntimeErrorOptions) {
127+
throw new Error('Expected options to be injected.');
128+
}
117129
return (
118130
<RuntimeErrorContainer
119131
errorRecords={currentRuntimeErrorRecords}
120132
close={dismissRuntimeErrors}
133+
launchEditorEndpoint={currentRuntimeErrorOptions.launchEditorEndpoint}
121134
/>
122135
);
123136
}

0 commit comments

Comments
 (0)