From 5075981a902e9ea7810d068cc3a84cbc15ff6292 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 26 Jun 2018 13:49:11 -0400 Subject: [PATCH] fix handling of fatal errors - fixes #289 --- src/api/dev.ts | 43 ++++++++++++++++++++++++++++++++----------- src/api/interfaces.ts | 1 + src/cli/dev.ts | 5 +++-- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/api/dev.ts b/src/api/dev.ts index 0b92097..712b302 100644 --- a/src/api/dev.ts +++ b/src/api/dev.ts @@ -33,6 +33,7 @@ class Watcher extends EventEmitter { server: Deferred; }; + crashed: boolean; restarting: boolean; current_build: { changed: Set; @@ -130,10 +131,16 @@ class Watcher extends EventEmitter { // TODO watch the configs themselves? const compilers = create_compilers({ webpack: this.dirs.webpack }); + let log = ''; + const emitFatal = () => { this.emit('fatal', { - message: `Server crashed` + message: `Server crashed`, + log }); + + this.crashed = true; + this.proc = null; }; this.watch(compilers.server, { @@ -149,18 +156,30 @@ class Watcher extends EventEmitter { this.deferreds.client.promise.then(() => { const restart = () => { - ports.wait(this.port).then((() => { - this.emit('ready', { - port: this.port, - process: this.proc - }); + log = ''; + this.crashed = false; - this.deferreds.server.fulfil(); + ports.wait(this.port) + .then((() => { + this.emit('ready', { + port: this.port, + process: this.proc + }); - this.dev_server.send({ - status: 'completed' + this.deferreds.server.fulfil(); + + this.dev_server.send({ + status: 'completed' + }); + })) + .catch(err => { + if (this.crashed) return; + + this.emit('fatal', { + message: `Server is not listening on port ${this.port}`, + log + }); }); - })); }; if (this.proc) { @@ -180,10 +199,12 @@ class Watcher extends EventEmitter { }); this.proc.stdout.on('data', chunk => { + log += chunk; this.emit('stdout', chunk); }); this.proc.stderr.on('data', chunk => { + log += chunk; this.emit('stderr', chunk); }); @@ -301,7 +322,7 @@ class Watcher extends EventEmitter { if (err) { this.emit('error', { type: name, - error: err + message: err.message }); } else { const messages = format_messages(stats); diff --git a/src/api/interfaces.ts b/src/api/interfaces.ts index b896477..e1ac627 100644 --- a/src/api/interfaces.ts +++ b/src/api/interfaces.ts @@ -12,6 +12,7 @@ export type ErrorEvent = { export type FatalEvent = { message: string; + log?: string; }; export type InvalidEvent = { diff --git a/src/cli/dev.ts b/src/cli/dev.ts index daf1306..cfc3414 100644 --- a/src/cli/dev.ts +++ b/src/cli/dev.ts @@ -36,11 +36,12 @@ export function dev(opts: { port: number, open: boolean }) { watcher.on('error', (event: events.ErrorEvent) => { console.log(`${colors.red(`✗ ${event.type}`)}`); - console.log(`${colors.red(event.error.message)}`); + console.log(`${colors.red(event.message)}`); }); watcher.on('fatal', (event: events.FatalEvent) => { - console.log(`${colors.bold.red(`> ${event.error.message}`)}`); + console.log(`${colors.bold.red(`> ${event.message}`)}`); + if (event.log) console.log(event.log); }); watcher.on('build', (event: events.BuildEvent) => {