How to generate an error in a Gulp task

gulp
This post is old, and probably obsolete

When writing a Gulp task that doesn't involve streams, how do you throw an error?

Motivation

Gulp, is a popular javscript build tool for web development. Gulp tasks are based around streams; but sometimes streams are too clumsy when you want to do a simple task. Say you want to check a JSON file conforms to certain rule. It's much easier to require the file, check what you need to check, and then throw an error if you need to than it is opening the file as a stream and validating it.

But how do you throw an error in Gulp "the proper way", i.e. not just by throwing a standard JS error?

Validating a package.json file

I had to validate a package json file to make sure all packages were installed with the --save-dev flag. In other words, all dependencies should be in exact semantic format, 1.2.3 instead of the default ^1.2.3 or ~1.2.3. It is simply enough in plain node, without the extra complication of streams - you require package.json, then test each dependency.

gulp.task(taskName, function (cb) {
  var gutil = require("gulp-util");
  var packageData = require("./package.json");

  // we test all three types of dependencies
  ["devDependencies", "dependencies", "optionalDependencies"]
  .forEach(function validateAnObj(key) {

    // load each dependency
    Object.keys(packageData[key])
    .forEach(function validateAField(field) {

      // check the version complies
      var hasInvalidVersion = (/[^0-9.]/.test(packageData[key][field]));

      // this is where the magic happens
      if (hasInvalidVersion) {
        throw new gutil.PluginError({
          plugin: taskName,
          message: field + " in " + key + " has non compliant versioning: " + packageData[key][field]
        });
      }
    });
  });
});

Throwing an error with gulp

The easiset way to throw a gulp-y error is to use gulp-util, which has a PluginError that can be thrown. Here is the documentation for PluginError. plugin and message get outputted on separate lines; they are basically a title message and a message body. There are also a couple of options that can be passed, do refer to the documentation.

This is not using gulp the way it was meant to be

There isn't always a benefit in turning simple problems into a stream problem. Hope this info was useful.