From a54f77cd9acea6bd078e596193c46ff7a2fff27b Mon Sep 17 00:00:00 2001 From: 014-code <2402143478@qq.com> Date: Sat, 18 Jul 2026 22:04:27 +0800 Subject: [PATCH] fix: avoid HTTP EOF exception decode log --- conn_http.go | 6 +++++- conn_http_exception_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/conn_http.go b/conn_http.go index 18ac811d69..3a88bec01a 100644 --- a/conn_http.go +++ b/conn_http.go @@ -436,6 +436,10 @@ func (h *httpConnect) readData(reader *chproto.Reader, timezone *time.Location, // Try to decode the block if err := block.Decode(reader, h.revision); err != nil { + if errors.Is(err, io.EOF) && (captureBuffer == nil || !bytes.Contains(captureBuffer.Bytes(), []byte("__exception__"))) { + return nil, io.EOF + } + // Decode failed - check if captured data contains exception marker // The decode error typically happens because it tries to read the // "__exception__" marker as binary data @@ -454,7 +458,7 @@ func (h *httpConnect) readData(reader *chproto.Reader, timezone *time.Location, if n > 0 && captureBuffer != nil { captureBuffer.Write(buf[:n]) } - if readErr != nil { + if readErr != nil && !errors.Is(readErr, io.EOF) { h.logger.Error("HTTP read data: decode error while parsing exception block", slog.Any("error", err)) } diff --git a/conn_http_exception_test.go b/conn_http_exception_test.go index 03c2b75209..6acfe850e6 100644 --- a/conn_http_exception_test.go +++ b/conn_http_exception_test.go @@ -2,8 +2,13 @@ package clickhouse import ( "bytes" + "errors" + "io" + "log/slog" "strings" "testing" + + chproto "github.com/ClickHouse/ch-go/proto" ) func TestParseExceptionFromBytes(t *testing.T) { @@ -119,3 +124,22 @@ func TestCapturingReader(t *testing.T) { }) } } + +func TestHTTPReadDataEOFDoesNotLogDecodeError(t *testing.T) { + var logBuf bytes.Buffer + h := &httpConnect{ + logger: slog.New(slog.NewTextHandler(&logBuf, &slog.HandlerOptions{Level: slog.LevelDebug})), + } + + reader := chproto.NewReader(bytes.NewReader(nil)) + block, err := h.readData(reader, nil, &bytes.Buffer{}) + if !errors.Is(err, io.EOF) { + t.Fatalf("expected io.EOF, got %v", err) + } + if block != nil { + t.Fatalf("expected nil block, got %#v", block) + } + if got := logBuf.String(); got != "" { + t.Fatalf("expected no error log, got %q", got) + } +}