Skip to content

fix(dotnet): end the bridge socket on netcoredbg's close, not its exit (#878) - #892

Merged
debugmcpdev merged 2 commits into
mainfrom
fix/878-netcoredbg-bridge-close
Oct 10, 2026
Merged

debugmcpdev merged 2 commits into
mainfrom
fix/878-netcoredbg-bridge-close

Conversation

@debugmcpdev

Copy link
Copy Markdown
Collaborator

Summary

Fixes #878.

packages/adapter-dotnet/src/utils/netcoredbg-bridge-core.ts ended the proxy's socket on the child's exit event. Node fires exit when the process ends and close once its stdio streams have drained, so an output / exited / terminated frame netcoredbg wrote just before exiting could still be in the stdout pipe when the socket was closed — the same class as #860 ("last line before exit"). The Dart bridge (dap-stdio-bridge-core.ts) already carries the rule; this brings the netcoredbg bridge in line.

Changes

  • The socket is ended on the child's close, never on exit (exit only marks the child gone).
  • Once the child has exited, proxy bytes aimed at its stdin are dropped instead of written to a dead pipe, and an in-flight stdin error (EPIPE) is logged to the bridge's stderr instead of crashing the bridge — there was no stdin error listener before.
  • dotnet-utils.ts header: replaced "netcoredbg natively supports DAP over TCP … No bridge process is needed" with what the bridge is for; packages/adapter-dotnet/docs/dotnet-adapter.md no longer says the --server bug is Windows-only (its own next paragraph said all platforms).
  • changelog.d/878.fixed.md.

Tests (packages/adapter-dotnet/tests/unit/netcoredbg-bridge-core.test.ts, 9 → 12)

  • keeps the socket open across netcoredbg exit until its streams close, then ends it (issue #878) — emits exit, then a final Content-Length: 2\r\n\r\n{} on stdout, then close; asserts the client received the frame. Red before the fix: the client received '' (the frame was lost to the ended socket, which also raised ERR_STREAM_WRITE_AFTER_END into the socket error path).
  • stops forwarding socket bytes to netcoredbg stdin once it has exited (red before: the write went through).
  • logs a netcoredbg stdin error instead of dying on it (red before: unhandled error on stdin).
  • The existing cleans up on netcoredbg exit emitted only exit and would hang under the new rule; it now emits exit then close (cleans up once netcoredbg has closed).

Verification

  • pnpm exec vitest run --project unit packages/adapter-dotnet/tests — 170 passed.
  • npm run typecheck:all (ratchet 0/0), eslint on the touched files, pnpm changelog:check, node scripts/check-docs.mjs — clean.
  • Pre-push hook (unit + integration) passed.

Not observed live (the issue notes netcoredbg usually answers disconnect and lingers); the unit test is the reproduction of the race.

🤖 Generated with Claude Code

#878)

Node fires `exit` when the process ends and `close` once its stdio streams
have drained; the last DAP frames netcoredbg writes before exiting can
still be in the stdout pipe at `exit`, and ending the proxy's socket there
lost them (the #860 class). The bridge now ends the socket on `close`,
drops proxy bytes aimed at a stdin with no process behind it, and logs an
in-flight stdin error instead of dying on it — the rule the Dart bridge
already carries. The `dotnet-utils` header still said no bridge process
was needed; it now says what the bridge is for.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.30769% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...adapter-dotnet/src/utils/netcoredbg-bridge-core.ts 92.30% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

… bridge's close and socket errors (#878)

Review of #892: Node destroys the child's stdin before it emits `exit`, so
the `childEnded` flag is belt and braces — the stdin `error` listener is
what keeps an in-flight EPIPE from crashing the bridge; the comment now
says so. The bridge also writes one line when netcoredbg closes and one
when the proxy's socket errors (both land in the proxy log through the
adapter manager's sanitized stderr path), and a test pins that a child
closing after the proxy has gone neither throws nor double-ends.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@debugmcpdev
debugmcpdev merged commit 5446abe into main Oct 10, 2026
13 of 14 checks passed
@debugmcpdev
debugmcpdev deleted the fix/878-netcoredbg-bridge-close branch October 10, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(dotnet): netcoredbg bridge ends the socket on 'exit' instead of 'close'; dotnet-utils header still says no bridge is needed

2 participants