diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig index 0c489fa2ef35e0..bc2b65a09196a6 100644 --- a/src/bun.js/api/bun/socket.zig +++ b/src/bun.js/api/bun/socket.zig @@ -1036,6 +1036,8 @@ fn NewSocket(comptime ssl: bool) type { var promise = val.asPromise().?; const err_ = err.toErrorInstance(globalObject); promise.rejectOnNextTickAsHandled(globalObject, err_); + this.has_pending_activity.store(false, .Release); + this.poll_ref.unref(handlers.vm); } } diff --git a/test/js/bun/net/socket.test.ts b/test/js/bun/net/socket.test.ts index 881175b242fcfd..9ee60bc6318491 100644 --- a/test/js/bun/net/socket.test.ts +++ b/test/js/bun/net/socket.test.ts @@ -1,5 +1,5 @@ import { expect, it } from "bun:test"; -import { bunExe } from "harness"; +import { bunExe, expectObjectTypeCount } from "harness"; import { connect, spawn } from "bun"; it("should keep process alive only when active", async () => { @@ -91,6 +91,10 @@ it("should reject on connection error, calling both connectError() and rejecting ); }); +it("should not leak memory when connect() fails", async () => { + await expectObjectTypeCount("TCPSocket", 1, 100); +}); + // this also tests we mark the promise as handled if connectError() is called it("should handle connection error", done => { var data = {}; @@ -128,3 +132,7 @@ it("should handle connection error", done => { }, }); }); + +it("should not leak memory when connect() fails again", async () => { + await expectObjectTypeCount("TCPSocket", 1, 100); +});