55// Use of this source code is governed by a BSD-style
66// license that can be found in the LICENSE file.
77
8- // Package bufio is a simplified Golang bufio.
9- // It mainly avoids calling TCPConn.ReadFrom in Writer.ReadFrom because
10- // TCPConn.ReadFrom calls sys calls .
8+ // Package bufio is a simplified Golang bufio. It mainly changes:
9+ // - Avoid calling TCPConn.ReadFrom in Writer.ReadFrom because TCPConn.ReadFrom calls sys calls.
10+ // - Wrap the error with ErrWriteFail/ErrReadFail so that the caller knows which peer fails .
1111package bufio
1212
1313import (
14- "errors"
1514 "io"
15+
16+ "github.com/pingcap/tiproxy/lib/util/errors"
1617)
1718
1819const (
@@ -22,6 +23,9 @@ const (
2223var (
2324 ErrBufferFull = errors .New ("bufio: buffer full" )
2425 ErrNegativeCount = errors .New ("bufio: negative count" )
26+
27+ ErrReadFail = errors .New ("read failed" )
28+ ErrWriteFail = errors .New ("write failed" )
2529)
2630
2731// Buffered input.
@@ -250,9 +254,12 @@ func (b *Reader) Buffered() int { return b.w - b.r }
250254// This may make multiple calls to the Read method of the underlying Reader.
251255// If the underlying reader supports the WriteTo method,
252256// this calls the underlying WriteTo without buffering.
257+ //
258+ // Wrap the error with ErrWriteFail/ErrReadFail so that the caller knows which peer fails.
253259func (b * Reader ) WriteTo (w io.Writer ) (n int64 , err error ) {
254260 n , err = b .writeBuf (w )
255261 if err != nil {
262+ err = errors .Wrap (err , ErrWriteFail )
256263 return
257264 }
258265
@@ -280,7 +287,7 @@ func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
280287 b .err = nil
281288 }
282289
283- return n , b .readErr ()
290+ return n , errors . Wrap ( b .readErr (), ErrReadFail )
284291}
285292
286293var errNegativeWrite = errors .New ("bufio: writer returned negative count from Write" )
@@ -430,15 +437,17 @@ func (b *Writer) Write(p []byte) (nn int, err error) {
430437// supports the ReadFrom method, this calls the underlying ReadFrom.
431438// If there is buffered data and an underlying ReadFrom, this fills
432439// the buffer and writes it before calling ReadFrom.
440+ //
441+ // Wrap the error with ErrWriteFail/ErrReadFail so that the caller knows which peer fails.
433442func (b * Writer ) ReadFrom (r io.Reader ) (n int64 , err error ) {
434443 if b .err != nil {
435- return 0 , b .err
444+ return 0 , errors . Wrap ( b .err , ErrWriteFail )
436445 }
437446 var m int
438447 for {
439448 if b .Available () == 0 {
440449 if err1 := b .Flush (); err1 != nil {
441- return n , err1
450+ return n , errors . Wrap ( err1 , ErrWriteFail )
442451 }
443452 }
444453 nr := 0
@@ -450,7 +459,7 @@ func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
450459 nr ++
451460 }
452461 if nr == maxConsecutiveEmptyReads {
453- return n , io .ErrNoProgress
462+ return n , errors . Wrap ( io .ErrNoProgress , ErrReadFail )
454463 }
455464 b .n += m
456465 n += int64 (m )
@@ -461,12 +470,14 @@ func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
461470 if err == io .EOF {
462471 // If we filled the buffer exactly, flush preemptively.
463472 if b .Available () == 0 {
464- err = b .Flush ()
473+ if err = b .Flush (); err != nil {
474+ err = errors .Wrap (err , ErrWriteFail )
475+ }
465476 } else {
466477 err = nil
467478 }
468479 }
469- return n , err
480+ return n , errors . Wrap ( err , ErrReadFail )
470481}
471482
472483// buffered input and output
0 commit comments