mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Open editor from error-overlay (minor) (#4979)
This PR adds links to the [react-error-overlay](https://www.npmjs.com/package/react-error-overlay). This allows a developer to open a stack trace in its own editor. ![codelinking](https://user-images.githubusercontent.com/1265681/44278860-a63e0a80-a24f-11e8-9c69-c5365c026c58.gif) Closes #4813
This commit is contained in:
parent
0dd2b2aa74
commit
11816537c3
|
@ -6,9 +6,9 @@
|
|||
import {getEventSourceWrapper} from './eventsource'
|
||||
import formatWebpackMessages from './format-webpack-messages'
|
||||
import * as ErrorOverlay from 'react-error-overlay'
|
||||
// import url from 'url'
|
||||
import stripAnsi from 'strip-ansi'
|
||||
import {rewriteStacktrace} from '../source-map-support'
|
||||
import fetch from 'unfetch'
|
||||
|
||||
const {
|
||||
distDir
|
||||
|
@ -30,6 +30,16 @@ const {
|
|||
let hadRuntimeError = false
|
||||
let customHmrEventHandler
|
||||
export default function connect (options) {
|
||||
// Open stack traces in an editor.
|
||||
ErrorOverlay.setEditorHandler(function editorHandler ({ fileName, lineNumber, colNumber }) {
|
||||
fetch(
|
||||
'/_next/development/open-stack-frame-in-editor' +
|
||||
`?fileName=${window.encodeURIComponent(fileName)}` +
|
||||
`&lineNumber=${lineNumber || 1}` +
|
||||
`&colNumber=${colNumber || 1}`
|
||||
)
|
||||
})
|
||||
|
||||
// We need to keep track of if there has been a runtime error.
|
||||
// Essentially, we cannot guarantee application state was not corrupted by the
|
||||
// runtime error. To prevent confusing behavior, we forcibly reload the entire
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
"htmlescape": "1.1.1",
|
||||
"http-errors": "1.6.2",
|
||||
"http-status": "1.0.1",
|
||||
"launch-editor": "2.2.1",
|
||||
"loader-utils": "1.1.0",
|
||||
"minimist": "1.2.0",
|
||||
"mkdirp-then": "1.2.0",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { join, relative, sep, normalize } from 'path'
|
||||
import WebpackDevMiddleware from 'webpack-dev-middleware'
|
||||
import WebpackHotMiddleware from 'webpack-hot-middleware'
|
||||
import errorOverlayMiddleware from './lib/error-overlay-middleware'
|
||||
import del from 'del'
|
||||
import onDemandEntryHandler, {normalizePage} from './on-demand-entry-handler'
|
||||
import webpack from 'webpack'
|
||||
|
@ -186,6 +187,7 @@ export default class HotReloader {
|
|||
this.middlewares = [
|
||||
webpackDevMiddleware,
|
||||
webpackHotMiddleware,
|
||||
errorOverlayMiddleware,
|
||||
onDemandEntries.middleware()
|
||||
]
|
||||
}
|
||||
|
|
14
server/lib/error-overlay-middleware.js
Normal file
14
server/lib/error-overlay-middleware.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import url from 'url'
|
||||
import launchEditor from 'launch-editor'
|
||||
|
||||
export default function errorOverlayMiddleware (req, res, next) {
|
||||
if (req.url.startsWith('/_next/development/open-stack-frame-in-editor')) {
|
||||
const query = url.parse(req.url, true).query
|
||||
const lineNumber = parseInt(query.lineNumber, 10) || 1
|
||||
const colNumber = parseInt(query.colNumber, 10) || 1
|
||||
launchEditor(`${query.fileName}:${lineNumber}:${colNumber}`)
|
||||
res.end()
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}
|
|
@ -5,6 +5,35 @@ import { check, File, waitFor, getReactErrorOverlayContent } from 'next-test-uti
|
|||
|
||||
export default (context, render) => {
|
||||
describe('Error Recovery', () => {
|
||||
it('should have installed the react-overlay-editor editor handler', async () => {
|
||||
let browser
|
||||
const aboutPage = new File(join(__dirname, '../', 'pages', 'hmr', 'about.js'))
|
||||
aboutPage.replace('</div>', 'div')
|
||||
|
||||
try {
|
||||
browser = await webdriver(context.appPort, '/hmr/about')
|
||||
|
||||
// Wait for react-error-overlay
|
||||
await browser.waitForElementByCss('iframe', 2000)
|
||||
|
||||
// react-error-overlay uses the following inline style if an editorHandler is installed
|
||||
expect(await getReactErrorOverlayContent(browser)).toMatch(/style="cursor: pointer;"/)
|
||||
|
||||
aboutPage.restore()
|
||||
|
||||
await check(
|
||||
() => browser.elementByCss('body').text(),
|
||||
/This is the about page/
|
||||
)
|
||||
} finally {
|
||||
aboutPage.restore()
|
||||
|
||||
if (browser) {
|
||||
browser.close()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('should detect syntax errors and recover', async () => {
|
||||
let browser
|
||||
const aboutPage = new File(join(__dirname, '../', 'pages', 'hmr', 'about.js'))
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('loadGetInitialProps', () => {
|
|||
getInitialProps () {}
|
||||
}
|
||||
const rejectPromise = loadGetInitialProps(TestComponent, {})
|
||||
const error = new Error('"TestComponent.getInitialProps()" is defined as an instance method - visit https://err.sh/zeit/next.js/get-inital-props-as-an-instance-method for more information.')
|
||||
const error = new Error('"TestComponent.getInitialProps()" is defined as an instance method - visit https://err.sh/zeit/next.js/get-initial-props-as-an-instance-method for more information.')
|
||||
return expect(rejectPromise).rejects.toEqual(error)
|
||||
})
|
||||
|
||||
|
|
30
yarn.lock
30
yarn.lock
|
@ -1074,6 +1074,10 @@ array-equal@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
|
||||
|
||||
array-filter@~0.0.0:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec"
|
||||
|
||||
array-find-index@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
|
||||
|
@ -1089,6 +1093,14 @@ array-includes@^3.0.3:
|
|||
define-properties "^1.1.2"
|
||||
es-abstract "^1.7.0"
|
||||
|
||||
array-map@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
|
||||
|
||||
array-reduce@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b"
|
||||
|
||||
array-union@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
|
||||
|
@ -1778,7 +1790,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
|
|||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.0, chalk@^2.4.1:
|
||||
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.0, chalk@^2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
|
||||
dependencies:
|
||||
|
@ -4693,6 +4705,13 @@ kind-of@^6.0.0, kind-of@^6.0.2:
|
|||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
|
||||
|
||||
launch-editor@2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.2.1.tgz#871b5a3ee39d6680fcc26d37930b6eeda89db0ca"
|
||||
dependencies:
|
||||
chalk "^2.3.0"
|
||||
shell-quote "^1.6.1"
|
||||
|
||||
lazy-cache@^0.2.3:
|
||||
version "0.2.7"
|
||||
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65"
|
||||
|
@ -7058,6 +7077,15 @@ shebang-regex@^1.0.0:
|
|||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
|
||||
|
||||
shell-quote@^1.6.1:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767"
|
||||
dependencies:
|
||||
array-filter "~0.0.0"
|
||||
array-map "~0.0.0"
|
||||
array-reduce "~0.0.0"
|
||||
jsonify "~0.0.0"
|
||||
|
||||
shellwords@^0.1.0, shellwords@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
|
||||
|
|
Loading…
Reference in a new issue