Skip to content

internal/jsonrpc2: wrap writeErr with %w so errors.Is works for consumers#1105

Open
mybytecode wants to merge 1 commit into
modelcontextprotocol:mainfrom
mybytecode:fix/errserverclosing-wrap-writeerr
Open

internal/jsonrpc2: wrap writeErr with %w so errors.Is works for consumers#1105
mybytecode wants to merge 1 commit into
modelcontextprotocol:mainfrom
mybytecode:fix/errserverclosing-wrap-writeerr

Conversation

@mybytecode

Copy link
Copy Markdown

Fixes #1098.

Summary

  • Change %v%w in conn.go:674 so that s.writeErr is properly wrapped in the error chain
  • Consumers can now use errors.Is(err, io.EOF) to detect clean host disconnects vs. real failures
  • Add regression test TestServerClosingErrorWrapsWriteErr

Details

When a connection shuts down due to a write failure, the error was built as:

err = fmt.Errorf("%w: %v", ErrServerClosing, s.writeErr)

The %v verb formats s.writeErr as text only — it is not in the error chain. This means errors.Is(err, io.EOF) returns false, and consumers cannot programmatically classify shutdown errors.

The fix changes %v to %w, which is supported since Go 1.20 (this SDK targets Go 1.25). With multiple %w verbs, fmt.Errorf returns an error implementing Unwrap() []error, making both ErrServerClosing and the underlying write error discoverable via errors.Is/errors.As.

Validation

  • go test ./internal/jsonrpc2/ -v — all pass
  • go test ./... — full suite passes
  • go vet ./... — clean

…mers

Fixes modelcontextprotocol#1098.

When a connection shuts down due to a write failure, the error was
formatted with %v for s.writeErr, which meant the underlying error
(typically io.EOF) was not in the error chain. Consumers could not use
errors.Is(err, io.EOF) to distinguish a clean host disconnect from a
real failure.

Change %v to %w so that both ErrServerClosing and the write error are
properly wrapped and discoverable via errors.Is/errors.As.
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.

jsonrpc2: server-closing error formats writeErr with %v, so errors.Is(err, io.EOF) is false for consumers

1 participant