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

[fix] write EPIPE error when attaching a file. (small repro) #830

Open
3 tasks done
eddienubes opened this issue Jan 29, 2024 · 4 comments
Open
3 tasks done

[fix] write EPIPE error when attaching a file. (small repro) #830

eddienubes opened this issue Jan 29, 2024 · 4 comments
Labels

Comments

@eddienubes
Copy link

eddienubes commented Jan 29, 2024

Describe the bug

Node.js version: v20.11.0

OS version: macOS Sonoma 14.2.1

Description:
When trying to attach 2 cat images (7mb and 560kb) node throws "write EPIPE" error.
The list of facts:

  1. The occurrence is intermittent
  2. Only when the suit of tests is run altogether.
  3. Running individual tests doesn't trigger anything.
  4. Even ridiculously small files (8 bytes) fail because of this.
  5. This scenario is also noticeable on v18 version of node.

A test snippet:

it('should upload cat test 1', async () => {
    const res = await request(app).post('/api')
      .attach('file', 'cat1.png')
      .attach('file2', 'cat2.png');

    expect(res.statusCode).toEqual(200);
    expect(res.body).toEqual({
      message: 'pass!'
    })
});

When I run ~14 of these in a single test suite the error occurs. (The test suit in the repro)
Also, for simplicity of this test suite I didn't use any multipart/form-data parser.

Perhaps, connected to #824 or #491.

We're unable to upgrade our repo with thousands of tests from v16 to v20 or even v18 because of this. Not sure how to proceed. Any advice will be highly appreciated!

Actual behavior

Node throws write EPIPE error supposedly due to how supertest handles streaming of these files.

Error: write EPIPE

    at afterWriteDispatched (node:internal/stream_base_commons:160:15)
    at writevGeneric (node:internal/stream_base_commons:143:3)
    at Socket._writeGeneric (node:net:950:11)
    at Socket._writev (node:net:959:8)
    at doWrite (node:internal/streams/writable:588:12)
    at clearBuffer (node:internal/streams/writable:765:5)
    at Socket.Writable.uncork (node:internal/streams/writable:523:7)
    at connectionCorkNT (node:_http_outgoing:955:8)
    at processTicksAndRejections (node:internal/process/task_queues:81:21)

Expected behavior

Should upload files without this error occurring.

Code to reproduce

A small repo with a test to reproduce the issue:
https://github.com/eddienubes/supertest-write-epipe-bug-repro

Checklist

  • I have searched through GitHub issues for similar issues.
  • I have completely read through the README and documentation.
  • I have tested my code with the latest version of Node.js and this package and confirmed it is still not working.
@eddienubes eddienubes added the bug label Jan 29, 2024
@ajfranzoia
Copy link

@eddienubes have you found a solution to this issue?

@eddienubes
Copy link
Author

eddienubes commented May 28, 2024

@ajfranzoia Hilariously, I've just created my own http testing library - https://github.com/eddienubes/sagetest
It's not mature yet (everything could be a breaking change atm), but I'm planning on finishing it soon.
Also, it's based on undici (the library behind node's native fetch), which is more performant than superagent.

@rawmind
Copy link

rawmind commented Jun 3, 2024

In my case, the issue occurred when a server responded with an error without reading the stream. if you debug this https://github.com/ladjs/superagent/blob/v9.0.2/src/node/index.js#L1211 line you find that data continued to write even after the request had completed, leading to an EPIPE error. It's reproducible on node >=18.

@thom-nic
Copy link

the issue occurred when a server responded with an error without reading the stream

@rawmind This tracks with what I'm seeing: in my case the intermittent failure I encounter is on a negative testcase where supertest calls attach() with the wrong field name. So it would make sense that the server does not consume it. (I'm using multer to handle the file upload.)

Any guesses how to avoid it, other than maybe changing the server to consume bad request data?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants