Unhandled stream error terminates Node process in gulp.src pipeline
0 reputation · 30 Jul 2023, 14:47 UTC
0 reputation · 30 Jul 2023, 14:47 UTC
Prevent a Gulp 4 pipeline from terminating the Node process when an upstream transform stream emits an error, using one error handler on the pipeline.
Stream errors move through the vinyl file system asynchronously, so try/catch cannot capture them. Plugins may swallow or reformat error events, and behavior depends on the plugin and gulp version.
Does an error listener attached only to gulp.dest() protect every upstream stream in the chain, or must each stream handle its own error event? Does the result differ when the pipeline is wrapped in gulp.series()?
33775 reputation · 31 Jul 2023, 01:13 UTC
No. An error listener on gulp.dest() only protects the destination stream and errors that upstream plugins explicitly forward to it. It does not catch errors emitted by gulp.src() or intermediate transform streams, because Node stream error events are scoped to the stream that emits them and .pipe() does not forward them automatically. Wrapping the pipeline in gulp.series() does not change this behavior; it only determines whether the next task runs after the current task fails.
error on the instance where the failure occurs..pipe() connects data flow, not error flow, unless the upstream implementation forwards errors.error can crash the Node process.gulp.series() aborts remaining tasks when a task errors, but it does not alter how errors move through a single pipeline.Whether a gulp.dest() listener sees an upstream error depends on the plugin. Some transform plugins forward errors downstream; others emit locally, swallow them, or reformat them. That variation makes a dest-only handler unreliable for this case.
gulp.src(), or use gulp-plumber after src to forward errors downstream instead of crashing.const { src, dest, series } = require('gulp');
const plumber = require('gulp-plumber');
function build() {
return src('src/**/*')
.on('error', function (err) {
console.error('Pipeline error:', err.message);
this.emit('end');
})
.pipe(plumber({ errorHandler: (err) => {
console.error('Plumber error:', err.message);
this.emit('end');
} }))
.pipe(dest('dist'));
}
exports.default = series(build, function next() {
console.log('next task');
});
Using both .on('error') on src and plumber is redundant; choose one approach per pipeline. The example shows the pattern, not a recommendation to stack handlers.
gulp.series(build, next) runs next only when build signals success. If build returns a stream that emits an unhandled error, Gulp aborts the series and next does not run. Handling the error inside build and emitting end lets the series continue.
gulp -v and confirm the major version is 4..on('error') only to dest(), and confirm the process exits.src() or plumber and confirm the process stays alive and the handler runs.gulp.series() with a second logging task to confirm abort versus continue behavior.One diagnostic detail that changes the recommendation: which transform plugin is throwing and whether it forwards errors through through2 or stream.pipeline. Plugin-specific documentation determines whether a dest-only listener could ever be sufficient.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.