summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Bridgewater <ruben@bridgewater.de>2018-05-31 12:11:22 +0200
committerAnna Henningsen <anna@addaleax.net>2018-06-08 01:24:39 +0200
commit32c51f10d33c686f2607559ff24a97d6c4a6f109 (patch)
tree0563de6d86fbebc4d9de2c461f645f2f3a8e4989
parent505bfdc7e4fc4f914ceca019706dbf06901dd361 (diff)
downloadandroid-node-v8-32c51f10d33c686f2607559ff24a97d6c4a6f109.tar.gz
android-node-v8-32c51f10d33c686f2607559ff24a97d6c4a6f109.tar.bz2
android-node-v8-32c51f10d33c686f2607559ff24a97d6c4a6f109.zip
stream: make the pipeline callback mandatory
Right now when not adding a callback to the pipeline it could cause an uncaught exception if there is an error. Instead, just make the callback mandatory as mostly done in all other Node.js callback APIs so users explicitly have to decide what to do in such situations. PR-URL: https://github.com/nodejs/node/pull/21054 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michaƫl Zasso <targos@protonmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
-rw-r--r--doc/api/stream.md6
-rw-r--r--lib/internal/streams/pipeline.js13
-rw-r--r--test/parallel/test-stream-pipeline.js19
3 files changed, 14 insertions, 24 deletions
diff --git a/doc/api/stream.md b/doc/api/stream.md
index 014b2f68b3..09ff2c02b1 100644
--- a/doc/api/stream.md
+++ b/doc/api/stream.md
@@ -1340,14 +1340,14 @@ run().catch(console.error);
rs.resume(); // drain the stream
```
-### stream.pipeline(...streams[, callback])
+### stream.pipeline(...streams, callback)
<!-- YAML
added: v10.0.0
-->
* `...streams` {Stream} Two or more streams to pipe between.
-* `callback` {Function} A callback function that takes an optional error
- argument.
+* `callback` {Function} Called when the pipeline is fully done.
+ * `err` {Error}
A module method to pipe between streams forwarding errors and properly cleaning
up and provide a callback when the pipeline is complete.
diff --git a/lib/internal/streams/pipeline.js b/lib/internal/streams/pipeline.js
index 849b3d39db..caa4042339 100644
--- a/lib/internal/streams/pipeline.js
+++ b/lib/internal/streams/pipeline.js
@@ -6,6 +6,7 @@
let eos;
const {
+ ERR_INVALID_CALLBACK,
ERR_MISSING_ARGS,
ERR_STREAM_DESTROYED
} = require('internal/errors').codes;
@@ -19,11 +20,6 @@ function once(callback) {
};
}
-function noop(err) {
- // Rethrow the error if it exists to avoid swallowing it
- if (err) throw err;
-}
-
function isRequest(stream) {
return stream.setHeader && typeof stream.abort === 'function';
}
@@ -66,8 +62,11 @@ function pipe(from, to) {
}
function popCallback(streams) {
- if (!streams.length) return noop;
- if (typeof streams[streams.length - 1] !== 'function') return noop;
+ // Streams should never be an empty array. It should always contain at least
+ // a single stream. Therefore optimize for the average case instead of
+ // checking for length === 0 as well.
+ if (typeof streams[streams.length - 1] !== 'function')
+ throw new ERR_INVALID_CALLBACK();
return streams.pop();
}
diff --git a/test/parallel/test-stream-pipeline.js b/test/parallel/test-stream-pipeline.js
index 12733d88a7..f735054e88 100644
--- a/test/parallel/test-stream-pipeline.js
+++ b/test/parallel/test-stream-pipeline.js
@@ -60,7 +60,7 @@ common.crashOnUnhandledRejection();
}, /ERR_MISSING_ARGS/);
assert.throws(() => {
pipeline();
- }, /ERR_MISSING_ARGS/);
+ }, /ERR_INVALID_CALLBACK/);
}
{
@@ -493,17 +493,8 @@ common.crashOnUnhandledRejection();
}
});
- read.on('close', common.mustCall());
- transform.on('close', common.mustCall());
- write.on('close', common.mustCall());
-
- process.on('uncaughtException', common.mustCall((err) => {
- assert.deepStrictEqual(err, new Error('kaboom'));
- }));
-
- const dst = pipeline(read, transform, write);
-
- assert.strictEqual(dst, write);
-
- read.push('hello');
+ assert.throws(
+ () => pipeline(read, transform, write),
+ { code: 'ERR_INVALID_CALLBACK' }
+ );
}