Skip to content

Commit 07064f0

Browse files
authored
Fix error handling in compiler watch() and run() (#157)
This changes it to be more like how webpack's watch mode handles it; if the compiler throws an error in `watch()` or `run()`, the middleware should continu to run instead of quitting.
1 parent 52c80d8 commit 07064f0

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

lib/Shared.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module.exports = function Shared(context) {
1111
if(typeof options.reporter !== "function") options.reporter = share.defaultReporter;
1212
if(typeof options.log !== "function") options.log = console.log.bind(console);
1313
if(typeof options.warn !== "function") options.warn = console.warn.bind(console);
14+
if(typeof options.error !== "function") options.error = console.error.bind(console);
1415
if(typeof options.watchDelay !== "undefined") {
1516
// TODO remove this in next major version
1617
options.warn("options.watchDelay is deprecated: Use 'options.watchOptions.aggregateTimeout' instead");
@@ -149,9 +150,7 @@ module.exports = function Shared(context) {
149150
var compiler = context.compiler;
150151
// start watching
151152
if(!options.lazy) {
152-
var watching = compiler.watch(options.watchOptions, function(err) {
153-
if(err) throw err;
154-
});
153+
var watching = compiler.watch(options.watchOptions, share.handleCompilerCallback);
155154
context.watching = watching;
156155
} else {
157156
context.state = true;
@@ -160,13 +159,17 @@ module.exports = function Shared(context) {
160159
rebuild: function rebuild() {
161160
if(context.state) {
162161
context.state = false;
163-
context.compiler.run(function(err) {
164-
if(err) throw err;
165-
});
162+
context.compiler.run(share.handleCompilerCallback);
166163
} else {
167164
context.forceRebuild = true;
168165
}
169166
},
167+
handleCompilerCallback: function(err) {
168+
if(err) {
169+
context.options.error(err.stack || err);
170+
if(err.details) context.options.error(err.details);
171+
}
172+
},
170173
handleRequest: function(filename, processRequest, req) {
171174
// in lazy mode, rebuild on bundle request
172175
if(context.options.lazy && (!context.options.filename || context.options.filename.test(filename)))

test/CompilerCallbacks.test.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
var should = require("should");
2+
var middleware = require("../middleware");
3+
require("mocha-sinon");
4+
5+
describe("CompilerCallbacks", function() {
6+
var plugins = {};
7+
var compiler = {
8+
watch: function() {},
9+
plugin: function(name, callback) {
10+
plugins[name] = callback;
11+
}
12+
};
13+
beforeEach(function() {
14+
plugins = {};
15+
});
16+
17+
it("watch error should be reported to console", function(done) {
18+
var error = new Error("Oh noes!");
19+
this.sinon.stub(compiler, "watch", function(opts, callback) {
20+
callback(error);
21+
});
22+
this.sinon.stub(console, "error");
23+
middleware(compiler);
24+
should.strictEqual(console.error.callCount, 1);
25+
should.strictEqual(console.error.calledWith(error.stack), true);
26+
done();
27+
});
28+
29+
it("options.error should be used on watch error", function(done) {
30+
this.sinon.stub(compiler, "watch", function(opts, callback) {
31+
callback(new Error("Oh noes!"));
32+
});
33+
middleware(compiler, {
34+
error: function(err) {
35+
err.should.startWith("Error: Oh noes!");
36+
done();
37+
}
38+
});
39+
});
40+
});

test/Lazy.test.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var should = require("should");
22
var middleware = require("../middleware");
3+
require("mocha-sinon");
34

45
var doneStats = {
56
hasErrors: function() {
@@ -30,6 +31,7 @@ describe("Lazy mode", function() {
3031
describe("builds", function() {
3132
var req = { method: "GET", url: "/bundle.js" };
3233
beforeEach(function() {
34+
this.sinon.stub(console, "error");
3335
instance = middleware(compiler, { lazy: true, quiet: true });
3436
});
3537
it("should trigger build", function(done) {
@@ -54,11 +56,13 @@ describe("Lazy mode", function() {
5456
});
5557
});
5658

57-
it("should pass through compiler error", function() {
58-
compiler.run.callsArgWith(0, new Error("MyCompilerError"));
59-
should.throws(function() {
60-
instance(req, res, next);
61-
}, "MyCompilerError");
59+
it("should pass through compiler error", function(done) {
60+
var error = new Error("MyCompilerError");
61+
compiler.run.callsArgWith(0, error);
62+
instance(req, res, next);
63+
should.strictEqual(console.error.callCount, 1);
64+
should.strictEqual(console.error.calledWith(error.stack), true);
65+
done();
6266
});
6367
});
6468

0 commit comments

Comments
 (0)