Potential UnhandledPromiseRejection?
In your readme example I believe there is potentially an UnhandledPromiseRejection.
The Transform stream has no error handler so I suspect the synchronous call to the flush callback will cause it to re-throw inside the promise scope.
@CodeMan99 What is the recommended fix? I believe I am running into this problem.
It works with gulp-download but I am trying to upgrade to gulp-download2.
This works:
const gulp = require('gulp');
const download = require('gulp-download2');
gulp.task('download_server', function (done) {
downloadFoo();
done();
});
async function downloadFoo() {
download("https://my.url/file.zip")
.pipe(gulp.dest('./server'));
}
As soon as I add decompress:
...
const decompress = require('gulp-decompress');
...
async function downloadFoo() {
download("https://my.url/file.zip")
.pipe(decompress())
.pipe(gulp.dest('./server'));
}
It fails with:
[11:10:29] Starting 'download_server'...
[11:10:29] Finished 'download_server' after 5.42 ms
[11:10:29] Downloading https://my.url/file.zip...
node:internal/process/promises:392
new UnhandledPromiseRejection(reason);
^
UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "[object Object]".
at throwUnhandledRejectionsMode (node:internal/process/promises:392:7)
at processPromiseRejections (node:internal/process/promises:475:17)
at process.processTicksAndRejections (node:internal/process/task_queues:106:32) {
code: 'ERR_UNHANDLED_REJECTION'
}
Node.js v22.11.0
@guw Basically, don't call cb synchronously.
The reason why this is needed is because the transform callback will internally re-throw the error. I don't exactly remember the reason for this (anti-)pattern. It certainly has been a hot minute. Anyway, this is a problem for any Promise pattern since everything is implicitly wrapped in try/catch.
I would get around this with setImmediate.
decompress(...)
.then(files => {
// ... happy path ... an error thrown here is sent to the `.catch` handler
})
.catch(err => {
// ... error path ... an error thrown here is sent to the promise chain (unhandled)
setImmediate(() => {
// ... next tick path ... an error thrown here is dropped
// which is OK since the callback is the error handling
cb(new PluginError('gulp-decompress:', err, {fileName: file.path}));
})
})