Must not wrap io.EOF
- Dominant language
- Go
- Stars
- 5.5k
- Forks
- 372
- PR merge metrics
- No merged PRs in 30d
Description
From the Go docs:
```go
// EOF is the error returned by Read when no more input is available.
// (Read must return EOF itself, not an error wrapping EOF,
// because callers will test for EOF using ==.)
// Functions should return EOF only to signal a graceful end of input.
// If the EOF occurs unexpectedly in a structured data stream,
// the appropriate error is either [ErrUnexpectedEOF] or some other error
// giving more detail.
var EOF = errors.New("EOF")
```
however, `Conn.reader` (and probably others) wrap io.EOF:
```go
func (c *Conn) reader(ctx context.Context) (_ MessageType, _ io.Reader, err error) {
defer errd.Wrap(&err, "failed to get reader")
// Wrap wraps err with fmt.Errorf if err is non nil.
// Intended for use with defer and a named error return.
// Inspired by https://github.com/golang/go/issues/32676.
func Wrap(err *error, f string, v ...any) {
if *err != nil {
*err = fmt.Errorf(f+": %w", append(v, *err)...)
}
}
```
This leads to errors such as https://github.com/hashicorp/yamux/pull/167.
I'd propose special-casing `Wrap` to check for `io.EOF` and would be happy to open a PR.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at errd.Wrap and its use in Conn.reader, then review the Go io.EOF documentation cited in the issue. Reproduce the wrapped-EOF case and check the project's existing tests; done means EOF remains directly comparable while other errors retain context.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100