添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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

This was for me a bit of surprising behavior. You can get a connection error after a response.

const http = require('http')
const server = http.createServer(function (req, res) {
  req.on('data', () => {})
  setTimeout(() => {
    // Prematurely ending the request. Usually due to a 5xx error.
    res.statusCode = 200
    res.end()
  }, 1000)
server.listen(0, function () {
  const req = http.request({
    port: this.address().port,
    method: 'POST',
    path: '/'
  req.on('response', res => {
    console.log("!", res.statusCode)
    clearInterval(interval)
  const interval = setInterval(() => {
    req.write(Buffer.alloc(32))
  }, 1000)

Which sometimes prints:

! 200
events.js:167
      throw er; // Unhandled 'error' event
Error: read ECONNRESET
    at TCP.onStreamRead (internal/stream_base_commons.js:111:27)
Emitted 'error' event at:
    at Socket.socketErrorListener (_http_client.js:391:9)
    at Socket.emit (events.js:182:13)
    at emitErrorNT (internal/streams/destroy.js:82:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)

I can't quite decide if this is wrong or right. I feel like it should either be a response or an error, not both... at least it should be consistent and happen just sometimes... Anyone, got any input?

[nodemon] to restart at any time, enter `rs` [nodemon] watching: *.* [nodemon] starting `node test.js` ! 200 ^Cnxt$ nodemon test.js [nodemon] 1.19.0 [nodemon] to restart at any time, enter `rs` [nodemon] watching: *.* [nodemon] starting `node test.js` ! 200 ^Cnxt$ nodemon test.js [nodemon] 1.19.0 [nodemon] to restart at any time, enter `rs` [nodemon] watching: *.* [nodemon] starting `node test.js` ! 200 events.js:167 throw er; // Unhandled 'error' event Error: read ECONNRESET at TCP.onStreamRead (internal/stream_base_commons.js:111:27) Emitted 'error' event at: at Socket.socketErrorListener (_http_client.js:391:9) at Socket.emit (events.js:182:13) at emitErrorNT (internal/streams/destroy.js:82:8) at emitErrorAndCloseNT (internal/streams/destroy.js:50:3) at process._tickCallback (internal/process/next_tick.js:63:19) [nodemon] app crashed - waiting for file changes before starting...

@lpinca How about one of two possible simple mitigations?

  • Don't emit error after response .
  • Don't emit response if request is not ended.
  • I was able to reproduce on 10.15.3

    Now using node v10.15.3 (npm v6.4.1)
    nxt$ open test.js ^C
    nxt$ node test.js 
    ! 200
    nxt$ node test.js 
    ! 200
    nxt$ node test.js 
    ! 200
    nxt$ node test.js 
    ! 200
    nxt$ node test.js 
    ! 200
    nxt$ node test.js 
    ! 200
    nxt$ node test.js 
    ! 200
    nxt$ node test.js 
    ! 200
    events.js:174
          throw er; // Unhandled 'error' event
    Error: read ECONNRESET
        at TCP.onStreamRead (internal/stream_base_commons.js:111:27)
    Emitted 'error' event at:
        at Socket.socketErrorListener (_http_client.js:392:9)
        at Socket.emit (events.js:189:13)
        at emitErrorNT (internal/streams/destroy.js:82:8)
        at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
        at process._tickCallback (internal/process/next_tick.js:63:19)

    Using the following example I am able to reproduce the scenario every time on OSX:

    const http = require('http')
    const server = http.createServer(function (req, res) {
      res.end()
    server.listen(0, function () {
      const req = http.request({
        port: this.address().port,
        method: 'POST',
        path: '/'
      req.on('response', res => {
        req.write(Buffer.alloc(32))
      req.write(Buffer.alloc(32))
    

    Using the following example I am able to reproduce the scenario every time on OSX:

    const http = require('http')
    const server = http.createServer(function (req, res) {
      res.end()
    server.listen(0, function () {
      const req = http.request({
        port: this.address().port,
        method: 'POST',
        path: '/'
      req.on('response', res => {
        req.write(Buffer.alloc(32))
      req.write(Buffer.alloc(32))
    

    It's crashed on my Windows with node v10.13.5

    C:\Users\himself65\Desktop\Github\test>node index2.js
    events.js:174
          throw er; // Unhandled 'error' event
    Error: read ECONNRESET
        at TCP.onStreamRead (internal/stream_base_commons.js:111:27)
    Emitted 'error' event at:
        at Socket.socketErrorListener (_http_client.js:392:9)
        at Socket.emit (events.js:189:13)
        at emitErrorNT (internal/streams/destroy.js:82:8)
        at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
        at process._tickCallback (internal/process/next_tick.js:63:19)

    because the connection is not kept alive. Perhaps we should make req.write() throw/emit an error if used after the 'response' event is received.

    Sounds like a good idea. However, it still leaves things a bit tricky to use:

    const req = http.request({ ... })
      .pipe(req)
      .on('error', onError)
      .on('response', res => {
        src.unpipe(req) // IMPORTANT or you might get unexpected errors
    

    Could maybe req.write be a noop (i.e. dump) or return false after a response has been received? (yes, it sounds bad in my ear as well)

    Somebody has news about this bug?
    We have this problem in GCP with CloudRun nodejs app on alpine and calling mongodb.
    Thanks a lot for your support.

    To elaborate on the previous comment, It doesn't actually look like we're running into the error in the context of a network socket. We're running into the error through two node processes doing IPC over file descriptors. If the child process fails in some way, sometimes the parent process will fail with the ECONNRESET. No useful stack traces are generated.

    I am also seeing this error.
    strangely that it only happens on one of my js project, i see this constantly when i use webpack-dev-server
    i am using mac M1 version 12.1
    node version 16.14

    node:events:498
          throw er; // Unhandled 'error' event
    Error: read ECONNRESET
        at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20)
    Emitted 'error' event on ClientRequest instance at:
        at TLSSocket.socketErrorListener (node:_http_client:442:9)
        at TLSSocket.emit (node:events:520:28)
        at emitErrorNT (node:internal/streams/destroy:157:8)
        at emitErrorCloseNT (node:internal/streams/destroy:122:3)
        at processTicksAndRejections (node:internal/process/task_queues:83:21) {
      errno: -54,
      code: 'ECONNRESET',
      syscall: 'read'
    

    I am also seeing this error. strangely that it only happens on one of my js project, i see this constantly when i use webpack-dev-server i am using mac M1 version 12.1 node version 16.14

    node:events:498
          throw er; // Unhandled 'error' event
    Error: read ECONNRESET
        at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20)
    Emitted 'error' event on ClientRequest instance at:
        at TLSSocket.socketErrorListener (node:_http_client:442:9)
        at TLSSocket.emit (node:events:520:28)
        at emitErrorNT (node:internal/streams/destroy:157:8)
        at emitErrorCloseNT (node:internal/streams/destroy:122:3)
        at processTicksAndRejections (node:internal/process/task_queues:83:21) {
      errno: -54,
      code: 'ECONNRESET',
      syscall: 'read'
    

    +1 here -- exactly the same error when running webpack or webpack-dev-server. Both with 16.14.0 and 17.7.0.

    @im6 I was able to fix this on my end by removing the import-statement for the Google Font. Both in my repo as well as in the one you linked to this issue. Seems to be a problem with one of the style loaders rather than webpack or Node.

    Yes you are right @Anatanokami .
    It is @import() function in .less file that broke the app and emit the error.
    Thanks for pointing out.

    I can't reproduce this with v19.x on macOS. This issue is almost 4 years old and the http module has gone through a lot of changes in those years. The original bug almost certainly has been fixed.

    Me-too commenters: if you still hit this bug in the latest v18.x or v19.x, please file a new issue and include steps to reproduce.

    If you're seeing it with v16.x or v14.x, you may be out of luck. Those release lines are in maintenance mode and near their end of life.

    @bnoordhuis I made the same assumption with the new HTTP implementation but this seems to one level lower (possibly socket related race condition having to do with event handlers). It's difficult to reproduce in isolation but easy to reproduce in established projects that I can't share the source code to. We should definitely get a new issue opened up even without reproducible steps so that folks don't go crazy trying to debug and can share/collaborate.