gulp uses orchestrator to run tasks. orchestrator ignores error events of stream that task function returns. robrich/orchestrator#46
The author says that it is because the inconsistent implementations of gulp plugin streams. Some streams emit error event and emits end event later.
Let's see how the behavior affects your task. Here is a fake gulp plugin stream that always emit an error event.
function error() {
function transform(file, enc, callback) {
var err = new PluginError('ERROR', 'Some error');
this.push(file),
callback(err);
}
return through(transform);
}
The following task exits because the error()
stream's error event is not handled and error not handled error.
gulp.task('foo', function() {
return gulp.src('test/**/*.js')
.pipe(error())
.pipe(mocha());
});
The following task succeeds because the error()
stream's error event is ignored by orchestrator.
gulp.task('foo', function() {
return gulp.src('test/**/*.js')
.pipe(mocha())
.pipe(error());
To handle errors properly, multipipe and stream-combiner are good options. They pipe multiple streams and give us a single point to handle errors. In addition, it treats the last stream and the other streams equally.
gulp.task('test', function() {
return multipipe(
gulp.src('test/**/*.js'),
error(),
mocha()
);
});
gulp.task('ci', gulp.tasks.test.dep, function() {
return gulp.tasks.test.fn()
.on('error', function(err) { throw err; });
});
gulp.task('watch', function() {
gulp.watch(['src/**/*.js', 'test/**/*.js'], ['test']);
});