-
Notifications
You must be signed in to change notification settings - Fork 22
Conversation
Hmm, I'm not really sure that this is a good idea. I mean, ignoring errors isn't something I want to encourage by having a configuration option, |
This isn't ignoring errors - they will be emitted anyway, but stream processing will be continued. We using this in compiling separate files through coffee-script. Source stream emitting file paths and map processing them through coffee-script compiler. If one file failed to compile we want to continue process, just show the error (which, again, will be emitted). |
👍 |
@dominictarr In reference to findings in gulpjs/gulp#75 (comment), the map-stream's behaviour is that it'll stop iterating on error. The behaviour as it is currently implemented assumes that the next data chunk depends on the current. This is useful for streaming lines of text from a file. However, in the general case, this doesn't cover collections where items are independent of each other (e.g. collection of files). The following snippet demonstrates the issue: var es = require('event-stream');
// a hack to continue on error for streams
var continueOnError = function(stream) {
return stream
.on('error', function() {})
.on('newListener', function() {
this.listeners('error').forEach(function(f) {
if(f.name == 'onerror') this.removeListener('error', f);
}, this);
});
};
// something that returns stream using es.map internally
var plugin = function(filter, filter_func) {
if(filter_func == void 0)
filter_func = function(n) { return n; };
return es.map(function (data, cb) {
if(filter_func(data) == filter) return cb(new Error(filter+''));
console.log('caught in es.map: ' + data)
return cb(null, data);
});
};
es.readArray([1,2,3,4,5])
.pipe(continueOnError(plugin(3)))
.on('error', console.log)
.pipe(es.through(function(n) {
console.log('caught in es.through: ' + n);
this.emit('data', n);
})); Output:
From the output, despite our best efforts to do In addition, the error is emitted and caught from map-stream fine. The desired output is the following:
Hopefully this explains the need for this pull-request. |
👍 |
This is a bit fragile, and not a very clean change, since you need to include the hack to make pipe not stop on an error. this assumes that it can reliably detect pipe's internal error handler based on listener being named module.exports = function (map) {
var stream
return stream = es.map(function (data, cb) {
map(data, function (err, data) {
if(err) stream.emit('lineerror', err) cb()
else cb(null, data)
})
})
} I'd consider an option to emit a different event on error, |
the question is, what is the best name for a handleable error? |
also, question: in the context of your build system, how do you handle errors? do you retry? |
@dominictarr how about "failure"? There are a lot of synonyms for error that could be used As for handling errors it depends on the plugin or the user. gulp itself doesn't do any error handling at all. I think users still expect it to keep going even when there is an error. |
Also to note that errors handled/behaved as it's implemented by node.js stream. |
@contra can you give me a concrete example of something you are building with gulp, a type of error that may occur, and why you'd want to keep on going in that situation? I see from your website that gulp is a bulid tool, but I didn't see at first glance what sort of of things it is intended to build. In most cases I can imagine, like, a compiler, or even building css etc, The best case I can think of where sometimes I'd want this is when testing. Sometimes I might want to know all the tests that fail, rather than stopping on the first failed test. On the other hand, it's much simpler to just stop on the first error so normally that is fine, even in testing. |
@dominictarr Personally I agree with you and I think the whole thing should fail when one file does - people keep opening issues about this though and they want this behavior so I'd like to give them an option somehow to do things the way they want. I think most people want this option for testing/linting where an error may not be a reason to stop the whole show. |
I'm serious about wanting an concrete example. Can you link me to one of these issues? |
@dominictarr So am I but I'm not the one who's asking for this - gulpjs/gulp#75 (comment) |
@contra Since, if a gulp-plugin uses this internally, plugin devs would need to expose the map's config options through the plugin for this to be of any use. |
@dominictarr Also related gulpjs/gulp#91 |
@dashed you can modify this property from outside module. |
@floatdrop But you shouldn't really know what kind of stream the plugin returns; even if you looked at the source code. You just assume the stream it returns is compatible with nodejs streams. |
@dashed well, sometimes you should do The problem is - we already got tons of plugins on |
Aha, okay now this all makes sense. a watch stream is the best example. maybe you need something that works like stdout and stderr? Oh, by the way, I'd recommend using |
@dominictarr Yeah I realized this too - event-stream is useful for rapid prototyping though when you don't know exactly what you'll need. I've refactored all of my wiki examples to use |
@dominictarr errors are collected in the usual way where users have to attach Something like https://github.com/floatdrop/gulp-plumber monkey-patch the pipe method, and addresses the error collection you mentioned. |
@dominictarr I'm interested in any ideas you have for error management using pipelines like this - this has been one of the only pain points for gulp so far |
I'd like to clarify that gulp-plumber doesn't actually pass errors downstream. Just attach a default error listener. |
yeah, this is a tricky problem. node's streams are very simple, and don't propagate errors. I've also experimented with alternative stream models, pull-stream that propagate errors - pull-streams work great for object streams. They are lazy (pull only) and they are easy to combine: you can describe streams in terms of you can do this with node, but it feels clumsy: https://github.com/dominictarr/stream-combiner One way I'd be tempted to implement gulp is to make a stream of streams, maybe instead of using pipe, you could have a different method that handled errors also, gulp(
gulp.src('./src/*.coffee'),
coffee(),
gulp.dest('./dist')
) The streams can still be normal node streams, but |
Is it necessary to propagate errors? |
Propagating errors is very useful in the sorts of things that I've used pull-stream for. Say for example, you do an http request, and then stream that to a file via multiple transforms However, I think this isn't important for gulp. you really just need a way to see errors, but keep everything flowing. |
@dominictarr yep, this is what we want and this is what |
okay, so If you send me a pull request that optionally uses a different error name and continues, |
Added option for different error name and some tests. |
having a configurable error name is bad (because everyone will pick a different one), You should try and avoid configuration options - because each option adds edgecases. |
Sure thing. Done. |
oh, just one thing, can the opts argument be the second argument? All my stream modules have optional arguments in that order, |
Done (imo: this will be harder to read, but options is very rarely will be used). |
Maybe, but i think being consistent is more important. |
available in event-stream@3.1.0 |
It would be nice, if map can continue after error emitted.