Skip to content

App crashes on delayed promise await #61074

@ackava

Description

@ackava

Version

24

Platform

All

Subsystem

No response

What steps will reproduce the bug?

Delay in awaiting promise crashes the app, the delay occurs due to different pipelines are piped together, which results in delay, although try/catch is set, and it should catch rejected promise but instead app crashes.

import { createReadStream, createWriteStream } from "node:fs";
import { Readable } from "node:stream";
import { pipeline } from "node:stream/promises";

export default class LogReadable {

    static async from(reader, log) {
        // some logic to open a telemetry etc..
        await new Promise((r) => setTimeout(r, 100));
        return Readable.from(this.iterate(reader, log));
    }

    static async *iterate(readable, log) {
        let buffer = "";
        for await (const item of readable) {
            if (buffer.length < 4096) {
                if (item instanceof Buffer) {
                    buffer += item.toString("utf-8");
                } else {
                    buffer += item.toString();
                }
            }
            yield item;
        }
        log(buffer);
    }
}

try {
    const s = createReadStream("./a");

    const out = createWriteStream("./out1");

    const r = await LogReadable.from(new Readable.from(s));

    await pipeline(r, out, { end: true });

} catch (error) {
    console.error(error);
    console.error("Program closed with error");
}

How often does it reproduce? Is there a required condition?

This occurs often, specially when CPU is busy.

What is the expected behavior? Why is that the expected behavior?

Promise rejection should be caught and should not through an exception.

What do you see instead?

App crashes.

Additional information

I think the problem lies in the unhandled rejection is thrown before the lifetime of promise, expecting promise's error handler to be attached instantly is an issue here, as promises are asynchronous, the order of attaching error handler cannot be guaranteed, so such error should only be thrown after promise has been garbage collected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions