sindresorhus / p-limit

Run multiple promise-returning & async functions with limited concurrency
MIT License
1.84k stars 99 forks source link

AbortController throws inside p-limit #64

Open UnlimitedBytes opened 1 year ago

UnlimitedBytes commented 1 year ago

Describe the bug

I created a simple basic application which uses node-fetch to send some HTTP(S)-Requests and uses p-limit to reduce the amount of requests send at the same time. The problem is when the node-fetch requests get aborted by an AbortController they throw inside p-limit so I can't handle the AbortError.

Reproduction

I'm providing a stripdown version of the application which only contains the parts necessary to trigger the bug.

Here is the stripdown version with p-limit

import fetch, { FormData, File } from 'node-fetch';
import pLimit from 'p-limit';

async function sendRequest(abortController) {
    try {
        const formData = new FormData();
        formData.set('file', new File(['Some text here..'], 'a.txt'));

        await fetch('https://example.com', {
            method: 'POST',
            body: formData,
            signal: abortController.signal,
        });
    } catch {
        console.error("Something wen't wrong doing request.");
    }
}

(async () => {
    const limit = pLimit(10);
    const abortController = new AbortController();

    const jobs = [];
    for (let i = 0; i < 10; i++) {
        jobs.push(limit(() => sendRequest(abortController)));
    }

    abortController.abort();

    await Promise.allSettled(jobs);
    console.log('Done sending all requests.');
})();

which generates the following output:

...
Something wen't wrong doing request.
Something wen't wrong doing request.
Done sending all requests.
node:events:515
      throw er; // Unhandled 'error' event
      ^

AbortError: The operation was aborted.

Here is the stripdown version without p-limit

import fetch, { FormData, File } from 'node-fetch';

async function sendRequest(abortController) {
    try {
        const formData = new FormData();
        formData.set('file', new File(['Some text here..'], 'a.txt'));

        await fetch('https://example.com', {
            method: 'POST',
            body: formData,
            signal: abortController.signal,
        });
    } catch {
        console.error("Something wen't wrong doing request.");
    }
}

(async () => {
    const abortController = new AbortController();

    const jobs = [];
    for (let i = 0; i < 10; i++) {
        jobs.push(sendRequest(abortController));
    }

    abortController.abort();

    await Promise.allSettled(jobs);
    console.log('Done sending all requests.');
})();

which generates the following output:

...
Something wen't wrong doing request.
Something wen't wrong doing request.
Done sending all requests.

Severity

blocking all usage of p-limit - as I can't abort requests without crashing the entire application.

Best regards UnlimitedBytes

UnlimitedBytes commented 1 year ago

@sindresorhus maybe?

sindresorhus commented 1 year ago

The problem seems to be caused by https://github.com/sindresorhus/p-limit/commit/7b978e3d6801ffdd4ee29b3329b4a32d617607fc#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346R38

// @copperwall

UnlimitedBytes commented 1 year ago

BUMP @sindresorhus @copperwall please I will use the package but that blocks me from using it...

Rinse12 commented 1 year ago

Any updates? I'm having the same issue

tuhm1 commented 1 month ago

It's node-fetch's issue https://github.com/node-fetch/node-fetch/issues/1801.