Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do you handle errors in broken stream? #67

Open
adjavaherian opened this issue Aug 12, 2015 · 24 comments
Open

How do you handle errors in broken stream? #67

adjavaherian opened this issue Aug 12, 2015 · 24 comments

Comments

@adjavaherian
Copy link

I'm trying to use plumber to handle the errors. If compilation fails during watch, plumber keeps the pipe together, but webpack watch zombies out.

var gulp = require('gulp');
var webpack = require('webpack-stream');
var path = require('path');
var plumber = require('gulp-plumber');

gulp.task('webpack-client', function() {
    return gulp.src(path.join('app/rehydrate'))
        .pipe(plumber())
        .pipe(webpack( require(path.join('../..', 'webpack.config.js'))[0] ))
        .pipe(gulp.dest(path.join('public/dist')));
});
@danyan
Copy link

danyan commented Dec 24, 2015

Do you have a solution now?

@adjavaherian
Copy link
Author

No, I started doing something different. This seems to work well.

var gulp = require('gulp');
var webpack = require('webpack');
var path = require('path');
var gutil = require('gulp-util');
var nodemon  = require('nodemon');
var devConfig = require(path.join('../..', 'webpack.config.js'));

function onBuild(done) {
    return function(err, stats) {
        if (err) {
            gutil.log('Webpack: compilation error', err);
            if (done) {
                done();
            }
        } else {
            Object.keys(stats.compilation.assets).forEach(function(key) {
                gutil.log('Webpack: output ', gutil.colors.green(key));
            });
            gutil.log('Webpack: ', gutil.colors.blue('finished ', stats.compilation.name));
            if (done) {
                done();
            }
        }
    }
}

//dev watch
gulp.task('webpack-client-watch', function() {
    webpack(devConfig[0]).watch(100, function(err, stats) {
        onBuild()(err, stats);
        nodemon.restart();
    });
});

@phal0r
Copy link

phal0r commented Jan 9, 2016

Hi Guys,

I am using the following versions of the libs and can use plumber with default settings as outlined in the first comment in order to not break the stream and the webpack watch feature when a build error occurs:

"webpack": "^1.12.9"
"webpack-stream": "^3.0.1"
"gulp-plumber": "^1.0.1"

So there is no need anymore for custom error handling

Update: The watch task is still doing its job and every time a new build is made, but after the first error the build will be corrupt, until i restart the whole gulp task, so it's not working smooth yet :(

@iliakan
Copy link

iliakan commented Jan 16, 2016

Hi @phal0r is the task still actual for you?

@phal0r
Copy link

phal0r commented Jan 24, 2016

Hi @iliakan ,

yes it is. Right now we are using node-notify to send windows toasts, when compilation failed, so we can manually restart the gulp script. Nodemon like described before, could do it automatically, but since we are using the react loader restarting takes a lot of time, so a clean error handling would definitive be the nicer way to go.

@iliakan
Copy link

iliakan commented Jan 24, 2016

@phal0r there is a minor drawback in webpackStream. So I'm using a bare webpack. Made a small config with gulp env.

Let me know if that works for you (the build:js part):
https://gist.github.com/5f46d1c5ad9914e04ee1

@phal0r
Copy link

phal0r commented Jan 26, 2016

Hi @iliakan ,

thanks for the gist, but i don't understand how the recovery should work, when a compilation error occurs. Or do you mean, webpack itself is handling its errors well and webpack-stream is breaking it?

If this is the case i can't wait to refactor our gulpfile :)

@gkiely
Copy link

gkiely commented Jan 27, 2016

I'm seeing this error as well, can confirm the pipe remains but the bundling no longer occurs.

@iliakan
Copy link

iliakan commented Jan 27, 2016

@phal0r @gkiely I just checked, rebuilding works.
Here's the video: http://jmp.sh/9OwZmZW

Here's the sample project (don't forget npm install):
07-postcss-webpack.zip

@iliakan
Copy link

iliakan commented Jan 28, 2016

Is all ok?

@gkiely
Copy link

gkiely commented Jan 28, 2016

Hi @iliakan does that project use webpack-stream, I see it's commented out in the js task.

@iliakan
Copy link

iliakan commented Jan 29, 2016

@gkiely no, because webpack-stream does not allow to see when the initial build is complete. No point in using it. The build is handled solely by webpack & plugins anyway.

@gkiely
Copy link

gkiely commented Jan 30, 2016

@iliakan Nah I would prefer to use webpack-stream

@gkiely
Copy link

gkiely commented Jan 30, 2016

@shama I think this is a duplicate of issue #34

@phal0r
Copy link

phal0r commented Feb 9, 2016

@gkiely

I agree with @iliakan. Since webpack handles all optimization internally, the only reason for using webpack-stream is for convenient post-processing of the generated assets, but it does not boost performance, since webpack-stream reads the output from disk.

I followed the way with webpack.watch and without webpack-stream, but i only output if there was an error and the compilation timestamp.

@shama
Copy link
Owner

shama commented Feb 9, 2016

since webpack-stream reads the output from disk.

It reads from memory: https://github.com/shama/webpack-stream/blob/master/index.js#L143

@iliakan
Copy link

iliakan commented Feb 9, 2016

BTW, I actually saw how to do webpack-stream right. There is a way. And no, I didn't mean any optimization issues. There are other things though.

I'd suggest to agree on the following:

  • webpack-stream integration with gulp is limited.
    Plugins that rename files (gulp-rev and such) must not be placed after webpack-stream, because that would break dynamic loading and other path-releated webpack features. Webpack must know the exact paths.
  • with that in mind, we usually have all JS build handled solely by webpack.
  • hence, webpack-stream is not really required most of time.

P.S. I did not mean to say that the plugin is obsolete, it's actually looks like the best integration with gulp possible.

@phal0r
Copy link

phal0r commented Feb 16, 2016

@shama

Apologies, I just investigated prepareFile. You are totally right. I have the following scenario. where webpack-stream could give a huge performance boos:

A common code base and different customizing classes that override base behaviour. So i consider the following:

  • create a memory file system and read all assets and source code in there
  • use gulp preprocess plugins and webpack compiler several times
  • write output to disk

That means, gulp.src and webpack are reading from memory to memory, but this copy is necessary per run for transformations and should be no problem. So we need to able to pass a inputFileSystem to webpack similar to the outputFileSystem approach you are using. Do you think this is possible?

Sorry, this is OT, I started writing and this came to my mind right now :)

@sinedied
Copy link

Has someone finally found a workaround to this issue, other than @iliakan solution to use webpack directly?

@iliakan
Copy link

iliakan commented May 18, 2016

There is a solution with webpack-stream.

@sinedied
Copy link

Could you please elaborate? gulp-plumber catches errors, but there is no subsequent output as after the first error, so it not a solution.

@iliakan
Copy link

iliakan commented May 18, 2016

I'm sorry it was some time ago, can't find the code right now.

From what I remember - you can specify a callback for errors, or something like that.

@sinedied
Copy link

I already tried this, setting up a callback to catch errors and emit an end event to keep the gulp stream alive, the result is the same as with gulp-plumber.

@professorkolik
Copy link

Hi guys, any solution how to solve the problem?

After the error in js, pipe is alive but there is no recompiled file.

const gulplog = require('gulplog');
const named = require('vinyl-named');
const gulp = require('gulp');
const gulpLoadPlugins = require('gulp-load-plugins');
const webpackStream = require('webpack-stream');
const paths = require('../paths');

const webpack = webpackStream.webpack;
const $ = gulpLoadPlugins();
const webpackOption = require('../../webpack.config.babel');
module.exports = options => (callback) => {
  const isDevelopment = process.env.NODE_ENV.trim() === 'development';
  const jsSrcFiles = paths.src.js.files;
  const jsDestFolder = isDevelopment ? paths.build.js.folder : paths.prod.js.folder;
  let firstBuildReady = false;

  function done(err, stats) {
    firstBuildReady = true;
    if (err) { // hard error, see https://webpack.github.io/docs/node.js-api.html#error-handling
      return;  // emit('error', err) in webpack-stream
    }
    gulplog[stats.hasErrors() ? 'error' : 'info'](stats.toString({colors: true}));
  }

  /** task's options */
  const srcFiles = options.src || jsSrcFiles;
  const dest = options.dest || jsDestFolder;
  /** js assembly task */
  return gulp.src(srcFiles)
    .pipe($.plumber({
      errorHandler: $.notify.onError(err => ({
        title: 'Webpack',
        message: err.message
      }))
    }))
    .pipe(named())
    .pipe(webpackStream(webpackOption, null, done))
    .pipe($.if(!isDevelopment, $.uglify()))
    .pipe(gulp.dest(dest))
    .on('data', () => {
      if (firstBuildReady) {
        callback();
      }
    });
};

This solution is fix the issue #34 (comment)

But that's not the right way to fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants