Skip to content

Commit 1c32cf8

Browse files
authored
net, backend: add more error types to disconnection error (#490)
1 parent 233f456 commit 1c32cf8

File tree

6 files changed

+60
-31
lines changed

6 files changed

+60
-31
lines changed

pkg/proxy/backend/error.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func Error2Source(err error) ErrorSource {
9999
return SrcNone
100100
}
101101
// Disconnection errors may come from other errors such as ErrProxyNoBackend and ErrBackendHandshake.
102-
// ErrClientConn and ErrBackendConn may include non-connection errors.
102+
// ErrClientConn and ErrBackendConn may include non-connection errors such as wrong PPV2 format, TLS cert error.
103103
if pnet.IsDisconnectError(err) {
104104
if errors.Is(err, ErrClientConn) {
105105
return SrcClientNetwork

pkg/proxy/net/error.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
package net
55

66
import (
7+
"context"
8+
"io"
9+
"os"
10+
"syscall"
11+
712
"github.com/pingcap/tiproxy/lib/util/errors"
813
)
914

@@ -15,3 +20,15 @@ var (
1520
ErrCloseConn = errors.New("failed to close the connection")
1621
ErrHandshakeTLS = errors.New("failed to complete tls handshake")
1722
)
23+
24+
// IsDisconnectError returns whether the error is caused by peer disconnection.
25+
func IsDisconnectError(err error) bool {
26+
switch {
27+
// Do not use os.Timeout(err) because it doesn't unwrap the error.
28+
case errors.Is(err, io.EOF), errors.Is(err, syscall.EPIPE), errors.Is(err, syscall.ECONNRESET),
29+
errors.Is(err, syscall.ECONNABORTED), errors.Is(err, syscall.ETIMEDOUT), errors.Is(err, os.ErrDeadlineExceeded),
30+
errors.Is(err, context.DeadlineExceeded):
31+
return true
32+
}
33+
return false
34+
}

pkg/proxy/net/error_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2024 PingCAP, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package net
5+
6+
import (
7+
"context"
8+
"os"
9+
"syscall"
10+
"testing"
11+
12+
"github.com/pingcap/tiproxy/lib/util/errors"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
func TestIsDisconnectErr(t *testing.T) {
17+
disConnErrors := []error{
18+
syscall.ETIMEDOUT,
19+
os.ErrDeadlineExceeded,
20+
context.DeadlineExceeded,
21+
errors.Wrap(errors.New("mock"), syscall.ETIMEDOUT),
22+
errors.Wrap(syscall.ETIMEDOUT, errors.New("mock")),
23+
}
24+
for _, err := range disConnErrors {
25+
require.True(t, IsDisconnectError(err))
26+
}
27+
28+
otherErrors := []error{
29+
syscall.ENOENT,
30+
errors.New("mock"),
31+
}
32+
for _, err := range otherErrors {
33+
require.False(t, IsDisconnectError(err))
34+
}
35+
}

pkg/proxy/net/net_err.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

pkg/proxy/net/packetio.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ func ReadFull(prw packetReadWriter, b []byte) error {
182182
for n := 0; n < m; {
183183
nn, err := prw.Read(b[n:])
184184
if err != nil {
185-
return errors.WithStack(err)
185+
return err
186186
}
187187
n += nn
188188
}
@@ -220,7 +220,7 @@ func (p *PacketIO) ApplyOpts(opts ...PacketIOption) {
220220
}
221221

222222
func (p *PacketIO) wrapErr(err error) error {
223-
return errors.WithStack(errors.Wrap(p.wrap, err))
223+
return errors.Wrap(p.wrap, err)
224224
}
225225

226226
func (p *PacketIO) LocalAddr() net.Addr {
@@ -371,7 +371,7 @@ func (p *PacketIO) ForwardUntil(dest *PacketIO, isEnd func(firstByte byte, first
371371
break
372372
}
373373
if header, err = p.readWriter.Peek(4); err != nil {
374-
return p.wrapErr(errors.Wrap(ErrReadConn, err))
374+
return p.wrapErr(errors.Wrap(ErrReadConn, errors.WithStack(err)))
375375
}
376376
length = int(header[0]) | int(header[1])<<8 | int(header[2])<<16
377377
}
@@ -405,7 +405,7 @@ func (p *PacketIO) OutPackets() uint64 {
405405

406406
func (p *PacketIO) Flush() error {
407407
if err := p.readWriter.Flush(); err != nil {
408-
return p.wrapErr(errors.Wrap(ErrFlushConn, err))
408+
return p.wrapErr(errors.Wrap(ErrFlushConn, errors.WithStack(err)))
409409
}
410410
return nil
411411
}
@@ -443,7 +443,7 @@ func (p *PacketIO) Close() error {
443443
}
444444
*/
445445
if err := p.readWriter.Close(); err != nil && !errors.Is(err, net.ErrClosed) {
446-
errs = append(errs, err)
446+
errs = append(errs, errors.WithStack(err))
447447
}
448448
return p.wrapErr(errors.Collect(ErrCloseConn, errs...))
449449
}

pkg/proxy/net/tls.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func (p *PacketIO) ServerTLSHandshake(tlsConfig *tls.Config) (tls.ConnectionStat
2828
conn := &tlsInternalConn{p.readWriter}
2929
tlsConn := tls.Server(conn, tlsConfig)
3030
if err := tlsConn.Handshake(); err != nil {
31-
return tls.ConnectionState{}, p.wrapErr(errors.Wrap(ErrHandshakeTLS, err))
31+
return tls.ConnectionState{}, p.wrapErr(errors.Wrap(ErrHandshakeTLS, errors.WithStack(err)))
3232
}
3333
p.readWriter = newTLSReadWriter(p.readWriter, tlsConn)
3434
return tlsConn.ConnectionState(), nil
@@ -39,7 +39,7 @@ func (p *PacketIO) ClientTLSHandshake(tlsConfig *tls.Config) error {
3939
conn := &tlsInternalConn{p.readWriter}
4040
tlsConn := tls.Client(conn, tlsConfig)
4141
if err := tlsConn.Handshake(); err != nil {
42-
return p.wrapErr(errors.Wrap(ErrHandshakeTLS, err))
42+
return p.wrapErr(errors.Wrap(ErrHandshakeTLS, errors.WithStack(err)))
4343
}
4444
p.readWriter = newTLSReadWriter(p.readWriter, tlsConn)
4545
return nil

0 commit comments

Comments
 (0)