Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add address to tryDial errors #1763

Merged
merged 17 commits into from May 2, 2024
Merged
37 changes: 31 additions & 6 deletions tcpdialer.go
Expand Up @@ -3,6 +3,7 @@ package fasthttp
import (
"context"
"errors"
"fmt"
"net"
"strconv"
"sync"
Expand Down Expand Up @@ -302,7 +303,7 @@ func (d *TCPDialer) dial(addr string, dualStack bool, timeout time.Duration) (ne
if err == nil {
return conn, nil
}
if err == ErrDialTimeout {
if errors.Is(err, ErrDialTimeout) {
return nil, err
}
idx++
Expand All @@ -316,7 +317,7 @@ func (d *TCPDialer) tryDial(
) (net.Conn, error) {
timeout := time.Until(deadline)
if timeout <= 0 {
return nil, ErrDialTimeout
return nil, wrapDialWithUpstream(ErrDialTimeout, addr)
}

if concurrencyCh != nil {
Expand All @@ -332,7 +333,7 @@ func (d *TCPDialer) tryDial(
}
ReleaseTimer(tc)
if isTimeout {
return nil, ErrDialTimeout
return nil, wrapDialWithUpstream(ErrDialTimeout, addr)
}
}
defer func() { <-concurrencyCh }()
Expand All @@ -346,15 +347,39 @@ func (d *TCPDialer) tryDial(
ctx, cancelCtx := context.WithDeadline(context.Background(), deadline)
defer cancelCtx()
conn, err := dialer.DialContext(ctx, network, addr)
if err != nil && ctx.Err() == context.DeadlineExceeded {
return nil, ErrDialTimeout
if err != nil {
if ctx.Err() == context.DeadlineExceeded {
return nil, wrapDialWithUpstream(ErrDialTimeout, addr)
}
return nil, wrapDialWithUpstream(err, addr)
}
return conn, err
return conn, nil
}

// ErrDialTimeout is returned when TCP dialing is timed out.
var ErrDialTimeout = errors.New("dialing to the given TCP address timed out")

// ErrDialWithUpstream wraps dial error with upstream info.
mdenushev marked this conversation as resolved.
Show resolved Hide resolved
type ErrDialWithUpstream struct {
Upstream string
wrapErr error
}

func (e *ErrDialWithUpstream) Error() string {
return fmt.Sprintf("error when dialing %s: %s", e.Upstream, e.wrapErr.Error())
}

func (e *ErrDialWithUpstream) Unwrap() error {
return e.wrapErr
}

func wrapDialWithUpstream(err error, upstream string) error {
return &ErrDialWithUpstream{
Upstream: upstream,
wrapErr: err,
}
}

// DefaultDialTimeout is timeout used by Dial and DialDualStack
// for establishing TCP connections.
const DefaultDialTimeout = 3 * time.Second
Expand Down