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

Potential UnhandledPromiseRejection? #16

Open
CodeMan99 opened this issue Mar 15, 2018 · 2 comments
Open

Potential UnhandledPromiseRejection? #16

CodeMan99 opened this issue Mar 15, 2018 · 2 comments

Comments

@CodeMan99
Copy link

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.

@guw
Copy link

guw commented Nov 9, 2024

@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

@CodeMan99
Copy link
Author

@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}));
        })
    })

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

2 participants