Your swallowError
function should look like this:
function swallowError (error) {
// If you want details of the error in the console
console.log(error.toString())
this.emit('end')
}
I think you have to bind this function on the error
event of the task that was falling, not the watch
task, because that's not where comes the problem, you should set this error callback on each task that may fail, like plugins that breaks when you have missed a ;
or something else, to prevent watch
task to stop.
Examples :
gulp.task('all', function () {
gulp.src('./app/script/*.coffee')
.pipe(coffee({ bare: true }))
.on('error', swallowError)
.pipe(gulp.dest('./public/js'))
gulp.src('css/*.scss')
.pipe(sass({ compass: true }))
.on('error', swallowError)
.pipe(cssmin())
.pipe(gulp.dest('dist'))
})
Alternately, if you don't mind to include another module, you can use the log function of gulp-util to keep you from declare an extra function in your gulpfile
:
.on('error', gutil.log)
But I may recommend having a look at the awesome gulp-plumber plugin, which is used to remove the onerror
handler of the error
event, causing the break of the streams. It's very simple to use and it stops you from catch all the tasks that may fail.
gulp.src('./app/script/*.coffee')
.pipe(plumber())
.pipe(coffee({ bare: true }))
.pipe(gulp.dest('./public/js'))
More info about this on this article by the creator of the concerned plugin.
The above examples didn't work for me. The following did though:
var plumber = require('gulp-plumber');
var liveReload = require('gulp-livereload');
var gutil = require('gulp-util');
var plumber = require('gulp-plumber');
var compass = require('gulp-compass');
var rename = require('gulp-rename');
var minifycss = require('gulp-minify-css');
var notify = require('gulp-notify');
gulp.task('styles', function () {
//only process main.scss which imports all other required styles - including vendor files.
return gulp.src('./assets/scss/main.scss')
.pipe(plumber(function (error) {
gutil.log(error.message);
this.emit('end');
}))
.pipe(compass({
config_file: './config.rb',
css: './css'
, sass: './assets/scss'
}))
//minify files
.pipe(rename({suffix: '.min'}))
.pipe(minifycss())
//output
.pipe(gulp.dest('./css'))
.pipe(notify({message: 'Styles task complete'}));
});
gulp.task('watch', function () {
liveReload.listen();
gulp.watch('assets/scss/**/*.scss', ['styles']);
});
(ex: *.coffee only)
If you want to work only with one format of files, then gulp-plumber
is your solution.
For example rich handled errors and warning for coffeescripting:
gulp.task('scripts', function() {
return gulp.src(['assets/scripts/**/*.coffee'])
.pipe(plumber())
.pipe(coffeelint())
.pipe(coffeelint.reporter())
.pipe(lintThreshold(10, 0, lintThresholdHandler))
.pipe(coffee({
bare: true
}))
.on('error', swallowError)
.pipe(concat('application.js'))
.pipe(gulp.dest('dist/scripts'))
.pipe(rename({ suffix: '.min' }))
.pipe(uglify())
.pipe(gulp.dest('dist/scripts'))
.pipe(notify({ message: 'Scripts task complete' }));
});
(ex: *.coffee and *.js at same time)
But if you won't to work with multiple types of file formats (for example: *.js
and *.coffee
), than i will post my solution.
I will just post a self explanatory code over here, with some description before.
gulp.task('scripts', function() {
// plumber don't fetch errors inside gulpif(.., coffee(...)) while in watch process
return gulp.src(['assets/scripts/**/*.js', 'assets/scripts/**/*.coffee'])
.pipe(plumber())
.pipe(gulpif(/[.]coffee$/, coffeelint()))
.pipe(coffeelint.reporter())
.pipe(lintThreshold(10, 0, lintThresholdHandler))
.pipe(gulpif(/[.]coffee$/, coffee({ // if some error occurs on this step, plumber won't catch it
bare: true
})))
.on('error', swallowError)
.pipe(concat('application.js'))
.pipe(gulp.dest('dist/scripts'))
.pipe(rename({ suffix: '.min' }))
.pipe(uglify())
.pipe(gulp.dest('dist/scripts'))
.pipe(notify({ message: 'Scripts task complete' }));
});
I faced the issue with gulp-plumber
and gulp-if
using gulp.watch(...
See related issue here: https://github.com/floatdrop/gulp-plumber/issues/23
So the best option for me was:
merge-stream
(that was made from event-stream
) into one and continue the job (i tried that first, and it work fine for me, so it is faster solution than previous one)Her is the main part of my code:
gulp.task('scripts', function() {
coffeed = gulp.src(['assets/scripts/**/*.coffee'])
.pipe(plumber())
.pipe(coffeelint())
.pipe(coffeelint.reporter())
.pipe(lintThreshold(10, 0, lintThresholdHandler))
.pipe(coffee({
bare: true
}))
.on('error', swallowError);
jsfiles = gulp.src(['assets/scripts/**/*.js']);
return merge([jsfiles, coffeed])
.pipe(concat('application.js'))
.pipe(gulp.dest('dist/scripts'))
.pipe(rename({ suffix: '.min' }))
.pipe(uglify())
.pipe(gulp.dest('dist/scripts'))
.pipe(notify({ message: 'Scripts task complete' }));
});
If to separate this into parts, then in each part there should be a result file created. For ex.:
gulp.task('scripts-coffee', function() {
return gulp.src(['assets/scripts/**/*.coffee'])
.pipe(plumber())
.pipe(coffeelint())
.pipe(coffeelint.reporter())
.pipe(lintThreshold(10, 0, lintThresholdHandler))
.pipe(coffee({
bare: true
}))
.on('error', swallowError)
.pipe(concat('application-coffee.js'))
.pipe(gulp.dest('dist/scripts'));
});
gulp.task('scripts-js', function() {
return gulp.src(['assets/scripts/**/*.js'])
.pipe(concat('application-coffee.js'))
.pipe(gulp.dest('dist/scripts'));
});
gulp.task('scripts', ['scripts-js', 'scripts-coffee'], function() {
var re = gulp.src([
'dist/scripts/application-js.js', 'dist/scripts/application-coffee.js'
])
.pipe(concat('application.js'))
.pipe(gulp.dest('dist/scripts'))
.pipe(rename({ suffix: '.min' }))
.pipe(uglify())
.pipe(gulp.dest('dist/scripts'))
.pipe(notify({ message: 'Scripts task complete' }));
del(['dist/scripts/application-js.js', 'dist/scripts/application-coffee.js']);
return re;
});
Here node modules and functions that were used:
// Load plugins
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
notify = require('gulp-notify'),
plumber = require('gulp-plumber'),
merge = require('ordered-merge-stream'),
replace = require('gulp-replace'),
del = require('del'),
gulpif = require('gulp-if'),
gulputil = require('gulp-util'),
coffee = require('gulp-coffee'),
coffeelint = require('gulp-coffeelint),
lintThreshold = require('gulp-coffeelint-threshold');
var lintThresholdHandler = function(numberOfWarnings, numberOfErrors) {
var msg;
gulputil.beep();
msg = 'CoffeeLint failure; see above. Warning count: ';
msg += numberOfWarnings;
msg += '. Error count: ' + numberOfErrors + '.';
gulputil.log(msg);
};
var swallowError = function(err) {
gulputil.log(err.toString());
this.emit('end');
};
I like to use gulp plumber because it can add a global listener to a task and have a meaningful message displayed.
var plumber = require('gulp-plumber');
gulp.task('compile-scss', function () {
gulp.src('scss/main.scss')
.pipe(plumber())
.pipe(sass())
.pipe(autoprefixer())
.pipe(cssnano())
.pipe(gulp.dest('css/'));
});
Reference : https://scotch.io/tutorials/prevent-errors-from-crashing-gulp-watch
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With