镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Uncaught Exception on node:stream/promises pipeline #58843

Description

@felixjb

Version

v22.16.0

Platform

Darwin Felixs-MacBook-Pro.local 24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:29 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6030 arm64

Subsystem

No response

What steps will reproduce the bug?

Given the following TypeScript function:

// Some details omitted

import { Transform } from "node:stream";
import { pipeline } from "node:stream/promises";

export const exportDataToCsvFile = async (
  dataStream: NodeJS.ReadableStream,
): Promise<void> => {
  const dataTransform = new Transform({
    objectMode: true,
    transform: (
      documentSnapshot: QueryDocumentSnapshot,
      _encoding,
      callback,
    ): void => {
      try {
        callback(null, documentSnapshot.data());
      } catch (error: unknown) {
        const errorInstance =
          error instanceof Error ? error : new Error(JSON.stringify(error));
        callback(errorInstance);
      }
    },
  });

  const csvStringifier = csv.stringify({ header: true });

  const filePath = storageService.buildFilePath({
    storeId: job.storeId,
    directory: job.name,
    name: `${getTimestamp()}.csv`,
  });
  const uploadStream = storageService.createUploadStream(filePath, {
    contentType: "text/csv",
  });

  try {
    await pipeline(dataStream, dataTransform, csvStringifier, uploadStream);
  } catch (error: unknown) {
    console.error("Failed to export data to CSV file", error);
  }
};

And the following Vitest test:

  it("should handle stream failures gracefully", async () => {
    // arrange - omitted 

    const failingDataStream = new Readable({
      read(): void {
        this.push("Not a document snapshot");
      },
    });

    await exportDataToCsvFile(failingDataStream);

    // assertions - omitted

The assertions pass and the test pass, at first, and after the test is finished an Unhandled Exception causes the test to fail:

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Uncaught Exception ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
TypeError: documentSnapshot.data is not a function
 ❯ Transform.transform [as _transform] src/jobs/application/exportDataToCsvFile.ts:36:72
     34|     ): void {
     35|       try {
     36|         callback(null, documentSnapshot.data());
       |                                                                        ^
     37|       } catch (error: unknown) {
 ❯ Transform._write node:internal/streams/transform:171:8
 ❯ writeOrBuffer node:internal/streams/writable:572:12
 ❯ _write node:internal/streams/writable:501:10
 ❯ Transform.Writable.write node:internal/streams/writable:510:10
 ❯ Readable.ondata node:internal/streams/readable:1009:22
 ❯ Readable.emit node:events:518:28
 ❯ Readable.read node:internal/streams/readable:782:10
 ❯ flow node:internal/streams/readable:1283:53
 ❯ resume_ node:internal/streams/readable:1262:3

This error originated in "test/integrations/jobs/exportDataToCsvFile.test.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
The latest test that might've caused the error is "should return execution failure and set job status to FAILED when the pipeline fails". It might mean one of the following:
- The error was thrown, while Vitest was running this test.
- If the error occurred after the test had been completed, this was the last documented test before it was thrown.
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯


 Test Files  1 passed (1)
      Tests  1 passed | 3 skipped (4)
     Errors  1 error
   Start at  12:51:17
   Duration  1.41s (transform 524ms, setup 0ms, collect 1.15s, tests 143ms, environment 0ms, prepare 33ms)

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

It happens regardless of how many .catch() or .on('error') are in place. It also does not respond to ending or destroying the streams.

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

I would like the pipeline to end when an error happens, and for all errors to be properly caught in the .catch() or try/catch.

What do you see instead?

Unhandled error

Additional information

No response

Activity

  1. islandryu commented on Jun 30, 2025

    @islandryu
    Member

    This is probably fixed by this PR.
    #55270
    It does not occur in version 24.0.0 or later.

  2. github-actions commented on Apr 19, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 210 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  3. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Apr 19, 2026
  4. github-actions commented on May 19, 2026

    @github-actions
    Contributor

    This issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 240 days).
    If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.streamIssues and PRs related to Node.js streams.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions