From 0c16dc8b0c38af5faf785dce65486d4d39bfca8e Mon Sep 17 00:00:00 2001 From: Yanhu007 Date: Tue, 14 Apr 2026 07:36:15 +0800 Subject: [PATCH] fix: do not wrap io.EOF in errd.Wrap 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 #561 --- internal/errd/wrap.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/errd/wrap.go b/internal/errd/wrap.go index c80d0a65..3ca36c46 100644 --- a/internal/errd/wrap.go +++ b/internal/errd/wrap.go @@ -2,13 +2,17 @@ package errd import ( "fmt" + "io" ) // 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. +// +// io.EOF is never wrapped because the Go convention requires +// callers to test for EOF using ==, not errors.Is. func Wrap(err *error, f string, v ...any) { - if *err != nil { + if *err != nil && *err != io.EOF { *err = fmt.Errorf(f+": %w", append(v, *err)...) } }