hoangvvo / next-connect

The TypeScript-ready, minimal router and middleware layer for Next.js, Micro, Vercel, or Node.js http/http2
https://www.npmjs.com/package/next-connect
MIT License
1.63k stars 65 forks source link

Error [ERR_STREAM_WRITE_AFTER_END]: write after end #140

Closed jjdechavez closed 2 years ago

jjdechavez commented 3 years ago

Good day everyone, I'm having issue when running my next-app it always keep throwing when I'm working with the api

events.js:353
      throw er; // Unhandled 'error' event
      ^

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at writeAfterEnd (_http_outgoing.js:694:15)
    at ServerResponse.end (_http_outgoing.js:815:7)
    at ServerResponse.end (/mnt/ExternalHDD/my/portfolio/node_modules/next/dist/compiled/compression/index.js:1:141519)
    at onerror (webpack-internal:///./node_modules/next-connect/dist/index.cjs:4:47)
    at eval (webpack-internal:///./node_modules/next-connect/dist/index.cjs:16:16)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async apiResolver (/mnt/ExternalHDD/my/portfolio/node_modules/next/dist/next-server/server/api-utils.js:8:1)
    at async DevServer.handleApiRequest (/mnt/ExternalHDD/my/portfolio/node_modules/next/dist/next-server/server/next-server.js:67:462)
    at async Object.fn (/mnt/ExternalHDD/my/portfolio/node_modules/next/dist/next-server/server/next-server.js:59:492)
    at async Router.execute (/mnt/ExternalHDD/my/portfolio/node_modules/next/dist/next-server/server/router.js:25:67)
    at async DevServer.run (/mnt/ExternalHDD/my/portfolio/node_modules/next/dist/next-server/server/next-server.js:69:1042)
    at async DevServer.handleRequest (/mnt/ExternalHDD/my/portfolio/node_modules/next/dist/next-server/server/next-server.js:34:504)
Emitted 'error' event on ServerResponse instance at:
    at writeAfterEndNT (_http_outgoing.js:753:7)
    at processTicksAndRejections (internal/process/task_queues.js:83:21) {
  code: 'ERR_STREAM_WRITE_AFTER_END'
}

I already tried to remove node_modules yarn.lock and update the npm. Stills throw the same error.

I just moved into Manjaro KDE 21.0.5 node v14.17.0 npm 7.14.0 next-connect ^0.10.1

You can check my repo to replicate it https://github.com/jjdechavez/portfolio/tree/feature/project-form After cloning, make sure to setup the env.local

Sample of env.local

BASE_URL='http://localhost:3000'

MONGODB_URI='mongodb:localhost:27017'
MONGODB_DB='$MONGODB_URI/portfolio'

SECRET_COOKIE_PASSWORD=mysecretcookiepassword

Then run yarn dev or npm run dev

Go to the /login page then it will throw the error

I hope someone could help me! TIA

hoangvvo commented 3 years ago

https://github.com/jjdechavez/portfolio/blob/feature/project-form/src/pages/api/login.ts#L21-L26

Consider when isAuth.login == false, both res.status(500).send(isAuth) and res.send(isAuth) is called, so that is why Error [ERR_STREAM_WRITE_AFTER_END]: write after end you are sending twice

hoangvvo commented 3 years ago

This is not related to this library btw, but try it out and see if it helps.

jjdechavez commented 3 years ago

Thank you for the response and I'm sorry if it's not library issue. Sorry for my logic error on my code. My I know whats the better approach to handle this kind of error.

I just updated the condition for isAuth.login == false

    if (!isAuth.login) {
      res.status(500).send(isAuth);
      return;
    }

It still throws the same error.

It's ok for me to close this issue.

jjdechavez commented 3 years ago

I saw same issue that I'm having right now, Tells that I should only use one res. After, trying the resolve issue.

    if (!isAuth.login) {
      return;
    }

It still throws the same error.

oncet commented 3 years ago

Having the same error.

import nc from "next-connect";
import { getSession } from "next-auth/client";

const handler = nc();

handler.put(async (req, res) => {
  const session = await getSession({ req });

  if (!session) {
    res.status(403).end();
  }

  if (!req.files) {
    res.status(400).end();
  }

  console.log('Request looks fine!');

  // Some logic here...

  res.end();
});

export default handler;

Anytime the flow goes into res.code().end() it throws ERR_STREAM_WRITE_AFTER_END.

If I use return it seems to work fine.

  if (!session) {
    return res.status(403).end();
  }

  if (!req.files) {
    return res.status(400).end();
  }
hoangvvo commented 3 years ago

I am suspecting that the session libraries are doing something with the response (such as automatically assign header on response sent), which accidentally cause this. I might have to look more into it though.

Can you try instead of res.status() or res.send() do:


res.statusCode = code;
res.end()
...
jjdechavez commented 3 years ago

@hoangvvo after checking the next-iron-session library, saw that in every call withIronSession method. It set the response header. You can check here: https://github.com/vvo/next-iron-session/blob/8280c18ac3ecb7314ecc531bf624e3cbfac211a1/lib/index.js#L72

Your right the issue came from into the session library.