Skip to content

Failed to catch AbortError from undici.request after server returns #3736

@SukkaW

Description

@SukkaW

Bug Description

The following minimum reproduction log ignore error and hey and then the entire process crashes with process.processTicksAndRejections. It seems that the abort error is leaked instead of being catched.

Reproducible By

const undici = require("undici");

(async () => {
  console.log(process.version);

  try {
    const controller = new AbortController();

    const request = async (url, id) => {
      const resp = await undici.request(url, {
        signal: controller.signal,
      });

      if (id === 2) {
        const error = new Error("bail out early");
        controller.abort(error);
        throw error;
      }

      console.log(resp.statusCode);
      // consume body
      await resp.body.arrayBuffer();
    };

    await Promise.any([
      request("https://cdn.skk.moe", 1),
      request("https://cdn.skk.moe/favicon.ico", 2),
    ]);
  } catch (e) {
    console.log("ignore error");
  }

  console.info("hey");
})();

Expected Behavior

The above minimum reproduction should log ignore error and hey and the process to exit with 0.

Logs & Screenshots

image
v22.6.0
ignore error
hey
node:events:498
      throw er; // Unhandled 'error' event
      ^

Error: bail out early
    at request (/home/runner/HauntingLikelyPaintprogram/index.js:15:23)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Promise.any (index 1)
    at async /home/runner/HauntingLikelyPaintprogram/index.js:30:5
Emitted 'error' event on BodyReadable instance at:
    at emitErrorNT (node:internal/streams/destroy:170:8)
    at emitErrorCloseNT (node:internal/streams/destroy:129:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

Node.js v22.6.0

Environment

Node.js 22.6.0 w/ undici 6.20.1

The error can be reproduced on both Linux and macOS.

Additional context

I am using Promise.any and undici.request to perform requests to multiple mirror URLs to get the fastest response and abort the rest. I also have a local cache and will bail out of all undici.request early if the fastest response matches certain criteria. I want to use try { } catch { } to catch the error and perform some logic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions