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

Error [ERR_INTERNAL_ASSERTION] on ServerResponse #34229

Closed
cermakondrej opened this issue Jul 6, 2020 · 9 comments
Closed

Error [ERR_INTERNAL_ASSERTION] on ServerResponse #34229

cermakondrej opened this issue Jul 6, 2020 · 9 comments
Labels
http Issues or PRs related to the http subsystem.

Comments

@cermakondrej
Copy link

cermakondrej commented Jul 6, 2020

What steps will reproduce the bug?

  1. clone https://github.com/randef-com/evidapp
  2. npm install
  3. docker-compose up (for database)
  4. nx serve api
  5. Send POST to localhost:3333/api/auth/register
    { "email": "[email protected]", "password": "aaaaa", "firstName": "Test", "lastName": "User" }

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

Right after the first request. I tried going commit back (which im sure worked just fine), but the error persisted, therefore I think its not related to the code itself.

What is the expected behavior?

User gets registered without node crashing

What do you see instead?

User gets registered, however node crashes with stacktrace:

Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issues

at assert (internal/assert.js:13:11)
at ServerResponse.detachSocket (_http_server.js:216:3)
at resOnFinish (_http_server.js:645:7)
at ServerResponse.emit (events.js:210:5)
at onFinish (_http_outgoing.js:686:10)
at onCorkedFinish (_stream_writable.js:690:5)
at afterWrite (_stream_writable.js:501:3)
at processTicksAndRejections (internal/process/task_queues.js:81:21)
@bnoordhuis bnoordhuis added http Issues or PRs related to the http subsystem. v12.x labels Jul 7, 2020
@bnoordhuis
Copy link
Member

Can you check with the latest v12.x, v12.18.2? There have been quite a few http fixes since v12.12.0.

@cermakondrej
Copy link
Author

@bnoordhuis The issue persists even on v12.18.2

@bnoordhuis
Copy link
Member

Can you post the stack trace you get with v12.18.2? (Verbatim, please.)

@cermakondrej
Copy link
Author

`
Error [ERR_INTERNAL_ASSERTION]: This is caused by either a bug in Node.js or incorrect usage of Node.js internals.
Please open an issue with this stack trace at https://github.com/nodejs/node/issues

at assert (internal/assert.js:14:11)
at ServerResponse.detachSocket (_http_server.js:223:3)
at resOnFinish (_http_server.js:690:7)
at ServerResponse.emit (events.js:315:20)
at onFinish (_http_outgoing.js:723:10)
at onCorkedFinish (_stream_writable.js:673:5)
at afterWrite (_stream_writable.js:490:5)
at afterWriteTick (_stream_writable.js:477:10)
at processTicksAndRejections (internal/process/task_queues.js:83:21)

`
It is pretty much the same. No idea, how to get more verbose logs, since I am running it through angular CLI and this is all it returns even with verbose flag :/

@KuthorX
Copy link
Contributor

KuthorX commented Jul 7, 2020

After I comment _http_server.js line 234 of master branch and build

assert(socket._httpMessage === this);

it print new message, which I think it maybe helpful.

Node version: v15.0.0-pre

(node:40432) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at new NodeError (internal/errors.js:254:15)
    at ServerResponse.setHeader (_http_outgoing.js:541:11)
    at ServerResponse.header (/Users/<user>/Documents/code/github/evidapp/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/Users/<user>/Documents/code/github/evidapp/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/Users/<user>/Documents/code/github/evidapp/node_modules/express/lib/response.js:267:15)
    at ExpressAdapter.reply (/Users/<user>/Documents/code/github/evidapp/node_modules/@nestjs/platform-express/adapters/express-adapter.js:24:57)
    at ExceptionsHandler.handleUnknownError (/Users/<user>/Documents/code/github/evidapp/node_modules/@nestjs/core/exceptions/base-exception-filter.js:33:24)
    at ExceptionsHandler.catch (/Users/<user>/Documents/code/github/evidapp/node_modules/@nestjs/core/exceptions/base-exception-filter.js:17:25)
    at ExceptionsHandler.next (/Users/<user>/Documents/code/github/evidapp/node_modules/@nestjs/core/exceptions/exceptions-handler.js:16:20)
    at /Users/<user>/Documents/code/github/evidapp/node_modules/@nestjs/core/router/router-proxy.js:13:35
(Use `node --trace-warnings ...` to show where the warning was created)
(node:40432) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:40432) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.


@bnoordhuis
Copy link
Member

The offending line is here:

assert(socket._httpMessage === this);

And that condition should be logically impossible unless ServerResponse#detachSocket() is called twice somehow.

I had a quick look through your app but it's a bit too big for me to get a good mental picture of how everything slots together.

In light of @KuthorX's comment, my guess is that express or nestjs tries to send a second response when the first one has already been sent.

The ERR_INTERNAL_ASSERTION exception that node throws isn't helpful and should be fixed but the root cause is probably not a node issue.

@cermakondrej
Copy link
Author

cermakondrej commented Jul 7, 2020

I changed the way how Status response is handled directly in the controller on nestjs.
(randef-com/evidapp@a13fa4a)
It indeed looks like bug directly in my code (copied from some other repository tbh)

We can close this since it has been resolved as issue on manipulating headers on repsonse object :)
Although it would be easier to get the error right away, without having to comment lines in nodejs source :/

@KuthorX
Copy link
Contributor

KuthorX commented Jul 7, 2020

The ERR_INTERNAL_ASSERTION exception that node throws isn't helpful and should be fixed but the root cause is probably not a node issue.

@bnoordhuis A solution may be adding a flag named finished into resOnFinish to check if res has called detachSocket?

function resOnFinish(req, res, socket, state, server) {
  if (!!res.finished) {
    return;
  }
  // Usually the first incoming element should be our request.  it may
  // be that in the case abortIncoming() was called that the incoming
  // array will be empty.
  assert(state.incoming.length === 0 || state.incoming[0] === req);

  state.incoming.shift();

  // If the user never called req.read(), and didn't pipe() or
  // .resume() or .on('data'), then we call req._dump() so that the
  // bytes will be pulled off the wire.
  if (!req._consuming && !req._readableState.resumeScheduled)
    req._dump();

  res.detachSocket(socket);
  clearIncoming(req);
  process.nextTick(emitCloseNT, res);

  if (res._last) {
    if (typeof socket.destroySoon === 'function') {
      socket.destroySoon();
    } else {
      socket.end();
    }
    res.finished = true;
  } else if (state.outgoing.length === 0) {
    if (server.keepAliveTimeout && typeof socket.setTimeout === 'function') {
      socket.setTimeout(server.keepAliveTimeout);
      state.keepAliveTimeoutSet = true;
    }
  } else {
    // Start sending the next message
    const m = state.outgoing.shift();
    if (m) {
      m.assignSocket(socket);
    }
  }
}

@targos
Copy link
Member

targos commented Apr 8, 2022

Closing this issue because v12.x goes EOL at the end of this month and no more releases are planned.

@targos targos closed this as completed Apr 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http Issues or PRs related to the http subsystem.
Projects
None yet
Development

No branches or pull requests

4 participants