How to ensure gulp-sass fails gracefully in 8.5.0?

Hi, all. I’ve started a new project and I’m having an issue with gulp-sass crashing gulp watch when selectors aren’t found.

I’ve tried figuring this out, but my node-fu isn’t too strong. I’ve narrowed it down to the sass() module in the cssTasks function sage/gulpfile.js at 8.5.0 · roots/sage · GitHub and I think it’s something do with the errLogToConsole.

I found this StackOverflow post, about a change in the way Gulp works from 1.x to 2.x. But I’m running gulp 3.9.1.

Has anyone else come across this issue? Thanks in advance.

The error message:
james@cthulhu:~/Development/example.com/site/web/app/themes/test-theme$ gulp
[06:33:49] Using gulpfile ~/Development/example.com/site/web/app/themes/test-theme/gulpfile.js
[06:33:49] Starting ‘clean’…
[06:33:49] Finished ‘clean’ after 6.48 ms
[06:33:49] Starting ‘default’…
[06:33:49] Starting ‘build’…
[06:33:49] Starting ‘wiredep’…
[06:33:49] Finished ‘default’ after 127 ms
[06:33:49] Finished ‘wiredep’ after 169 ms
[06:33:49] Starting ‘styles’…
assets/styles/sections/_section-hero.scss
Error: “.section–hero” failed to @extend “%bg-cover”.
The selector “%bg-cover” was not found.
Use “@extend %bg-cover !optional” if the extend should be able to fail.
on line 2 of assets/styles/sections/_section-hero.scss
>> @extend %bg-cover;
–^

events.js:160
      throw er; // Unhandled 'error' event
      ^
Error: assets/styles/sections/_section-hero.scss
Error: ".section--hero" failed to @extend "%bg-cover".
       The selector "%bg-cover" was not found.
       Use "@extend %bg-cover !optional" if the extend should be able to fail.
        on line 2 of assets/styles/sections/_section-hero.scss
>>   @extend %bg-cover;
   --^

    at options.error (/home/james/Development/example.com/site/web/app/themes/test-theme/node_modules/node-sass/lib/index.js:283:26)

What I’m running
node 6.9.1
npm 3.10.8
3.9.1

Project packages
├── asset-builder@1.1.0
├── browser-sync@2.18.2
├── del@2.2.2
├── gulp@3.9.1
├── gulp-autoprefixer@3.1.1
├── gulp-changed@1.3.2
├── gulp-concat@2.6.1
├── gulp-cssnano@2.1.2
├── gulp-flatten@0.3.1
├── gulp-if@2.0.2
├── gulp-imagemin@3.1.1
├── gulp-jshint@2.0.4
├── gulp-less@3.3.0
├── gulp-plumber@1.1.0
├── gulp-rename@1.2.2
├── gulp-rev@7.1.2
├── gulp-sass@2.3.2
├── gulp-sourcemaps@1.9.1
├── gulp-uglify@2.0.0
├── imagemin-pngcrush@5.0.0
├── jshint@2.9.4
├── jshint-stylish@2.2.1
├── lazypipe@1.0.1
├── merge-stream@1.0.1
├── minimist@1.2.0
├── run-sequence@1.2.2
├── traverse@0.6.6
└── wiredep@4.0.0

Where is %bg-cover actually defined? Can you try defining it on line 1 of _section-hero.scss and seeing if that clears the error. If it does then you might have simply included _section-hero.scss before you included the partial that contains its definition.

Hi, @cfx %bg-cover isn’t defined anywhere. But my issue relates to how gulp is handling this, rather than the definition itself.

Up until now, when I had an undefined or invalid Sass variable or css property, the gulp watch process would display the error and continue with the rest of the build.

Now, the gulp watch process crashes and I need to restart it when an error occurs. This is the issue I’m having, as I’d like it to just display the error and continue building, rather than crashing and requiring a restart.

I think this is something due to the gulp-sass module, but I haven’t been able to figure out how to catch this error and handle it properly, so that the gulp watch process doesn’t crash.

Thanks for your reply :slight_smile:

My experience has been that some errors fail gracefully and others simply don’t. Something like this generally isn’t reason enough for me to lose sight of my project and begin delving into gulp module source, especially when the error message itself gives you a way to allow the declaration to fail gracefully.

Thanks again for your reply. I’m not quite sure what you mean about the error message giving me a way to gracefully handle the exception so that gulp watch doesn’t crash.

I’ve tried modifying the cssTasks function as follows:

original, line 91 in the gulpfile.js - sage 8.5.0

.pipe(function() {
        return gulpif('*.scss', sass({
            outputStyle: 'nested', // libsass doesn't support expanded yet
            precision: 10,
            includePaths: ['.'],
            errLogToConsole: !enabled.failStyleTask
        }));
    })

replacing it with this:

.pipe(function() {
        return gulpif('*.scss', sass({
            outputStyle: 'nested', // libsass doesn't support expanded yet
            precision: 10,
            includePaths: ['.']
        }).on('error', function (err) {
            console.log(err.toString());
            this.emit('end');
        }));
    })

But no success, unfortunately.

I know it’s not a major issue, but if I make a spelling mistake, or use an incorrect variable name, gulp watch is crashing and requires manual restarting each time, which is quite frustrating.

If someone has encountered this before and has solved it with some sort of exception handler, which prevents gulp watch from crashing, I’d be very grateful.

What you need is Gulp-Plumber!

Prevent pipe breaking caused by errors from gulp plugins

Example:

var gulp = require('gulp'),
    config = require('../config').styles,
    plumber = require('gulp-plumber'),
    sass = require('gulp-sass'),
    sassGlob = require('gulp-sass-glob');

gulp.task('styles', function() {
  return gulp.src(config.src)
    .pipe(plumber({
      errorHandler: function(error) {
        console.log(error.message);
        this.emit('end');
      }
    }))
    .pipe(sassGlob())
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest(config.dest));
});
1 Like

What I mean is:

Use "@extend %bg-cover !optional" if the extend should be able to fail.

Thanks, @pconnors, I updated the styles task to include .pipe(plumber({errorHandler: onError})) and it’s not crashing now.

gulp.task('styles', ['wiredep'], function () {
var merged = merge();
manifest.forEachDependency('css', function (dep) {
    var cssTasksInstance = cssTasks(dep.name);
    if (!enabled.failStyleTask) {
        cssTasksInstance.on('error', function (err) {
            console.error(err.message);
            this.emit('end');
        });
    }
    merged.add(gulp.src(dep.globs, {base: 'styles'})
        .pipe(plumber({errorHandler: onError}))
        .pipe(cssTasksInstance));
});
return merged
    .pipe(writeToManifest('styles'));
});

var onError = function (err) {
console.log(err.toString());
this.emit('end');
};
3 Likes