node.jsgulpgulp-imagemin

Gulp image-min - How to continue after an error?


I am trying to run an image optimisation task on a folder with 1000s of images, unfortunately some of them are corrupted so the task keeps failing

I have tried to capture the error and continue, but its not working once it hits a corrupted image the task then aborts. Is there a way for this to continue running?

gulp.task('imgCompress', (done) => {
  gulp.src(imgMedia)
    .pipe(imagemin([
       mozjpeg({
         quality: 75
       }),

       pngquant({
         quality: [0.65, 0.80]
       })
    ]))

    .on('error', gutil.log)

    .pipe(gulp.dest(imgMediaDest))
    done();
});

Error:

{ Error: write EPIPE
    at WriteWrap.afterWrite [as oncomplete] (net.js:789:14)
  errno: 'EPIPE',
  code: 'EPIPE',
  syscall: 'write',
  stdout:
   <Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 00 01 00 00 ff e1 2b 18 45 78 69 66 00 00 4d 4d 00 2a 00 00 00 08 00 0b 01 0f 00 02 00 00 00 06 00 00 ... >,
  stderr: <Buffer >,
  failed: true,
  signal: null,
  cmd:
   '/private/var/www/website/m2/tools-media/node_modules/mozjpeg/vendor/cjpeg -quality 75',
  timedOut: false,
  killed: false,
  message: 'write EPIPE',
  name: 'Error',
  stack:
   'Error: write EPIPE\n    at WriteWrap.afterWrite [as oncomplete] (net.js:789:14)',
  __safety: undefined,
  _stack: undefined,
  plugin: 'gulp-imagemin',
  showProperties: true,
  showStack: false,
  fileName:
   '/private/var/www/website/m2/pub/media/catalog/product/1/i/1img_5232.jpg' }

Solution

  • You should be fine with gulp-plumber, which lets the stream continue after an error and even has an option to log error messages automatically without handling error events.

    Also note that you should not call done after creating a stream, but after the stream has terminated (you could for example listen to finish events). But it's easier to simply return the stream from the task function.

    const plumber = require('gulp-plumber');
    
    gulp.task('imgCompress', () => {
      return gulp.src(imgMedia)
        .pipe(plumber({ errorHandler: true }))
        .pipe(imagemin([
           mozjpeg({
             quality: 75
           }),
    
           pngquant({
             quality: [0.65, 0.80]
           })
        ]))
        .pipe(gulp.dest(imgMediaDest))
    });