Skip to content

fix: do not wrap io.EOF in errd.Wrap#562

Open
Yanhu007 wants to merge 1 commit intocoder:masterfrom
Yanhu007:fix/no-wrap-io-eof
Open

fix: do not wrap io.EOF in errd.Wrap#562
Yanhu007 wants to merge 1 commit intocoder:masterfrom
Yanhu007:fix/no-wrap-io-eof

Conversation

@Yanhu007
Copy link
Copy Markdown

Fixes #561

Problem

The errd.Wrap helper wraps all non-nil errors using fmt.Errorf("%w"). When io.EOF is returned (e.g. from Conn.reader), it becomes "failed to get reader: EOF". Per Go convention, io.EOF must never be wrapped:

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 ==.)

This breaks callers like io.Copy and bufio.Scanner that test err == io.EOF.

Fix

Skip wrapping in errd.Wrap when the error is exactly io.EOF:

func Wrap(err *error, f string, v ...any) {
    if *err != nil && *err != io.EOF {
        *err = fmt.Errorf(f+": %w", append(v, *err)...)
    }
}

The Go convention requires callers to test for io.EOF using ==,
not errors.Is. Wrapping io.EOF breaks this contract and causes
callers (e.g. io.Copy, bufio.Scanner) to fail to detect EOF.

The errd.Wrap helper is used with defer in several methods
(Conn.reader, etc.), causing io.EOF to be wrapped into errors
like 'failed to get reader: EOF'. These wrapped errors no longer
compare equal to io.EOF.

Skip wrapping when the error is exactly io.EOF.

Fixes coder#561
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.

Must not wrap io.EOF

1 participant