Skip to content

Uncaught exception in socket code: "Cannot read properties of null (reading 'finishWrite')" #46094

Open
@danfuzz

Description

@danfuzz

Version

v18.4.0

Platform

Linux i-00f751a18edbe3eb6.us-west-2.compute.internal 5.15.73-45.135.amzn2022.x86_64 #1 SMP Fri Oct 14 17:47:15 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

http2 (maybe actually net or tls)

What steps will reproduce the bug?

Apologies that I don't have an easy repro case yet. It's one of those "run my server for a while and then it does this." Near as I can tell, it's along these lines:

  1. Connection accepted to an Http2Server (via TLS socket).
  2. Session established.
  3. Session remains idle for five minutes. (No requests ever made.)
  4. My code notices the idleness and calls close() on the session. (Tick/turn concludes.)
  5. Boom! Uncaught exception: TypeError: Cannot read properties of null (reading 'finishWrite')

When I get a chance (hopefully soon) I will try to distill down a real example. Thanks for any help you can offer in the meantime.

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

Unclear. This shows up about once a day on my not-very-active server. It does correspond one-to-one with a call to session.close(). That is, every time my server does this right now, this uncaught exception seems to follow.

What is the expected behavior?

No uncaught exception. That is, either no exception at all, or an exception that can be safely caught and handled without shutting the system down.

What do you see instead?

This uncaught exception:

TypeError: Cannot read properties of null (reading 'finishWrite')
    at JSStreamSocket.finishWrite (node:internal/js_stream_socket:211:12)
    at Immediate.<anonymous> (node:internal/js_stream_socket:196:14)
    at process.processImmediate (node:internal/timers:471:21)
    at process.callbackTrampoline (node:internal/async_hooks:130:17)

Additional information

This is the actual code which sets up the timeout. The timeout time is 5 minutes, and the logger... call simply writes a structured log line.

    session.setTimeout(Http2Wrangler.#SESSION_TIMEOUT_MSEC, () => {
      logger?.idleTimeout();
      session.close();
    });

Http2Session.close() does accept an optional callback, which is documented as being bound to the close event. However, this code already binds a handler to close (which does not seem to be getting called before the uncaught exception is generated).

Metadata

Metadata

Assignees

No one assigned

    Labels

    http2Issues or PRs related to the http2 subsystem.tlsIssues and PRs related to the tls subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions