Skip to content

Commit 57dd3bc

Browse files
authored
swarm: fix Unwrap for DialError, implement Unwrap for TransportError (#2437)
1 parent cd930fa commit 57dd3bc

File tree

3 files changed

+70
-8
lines changed

3 files changed

+70
-8
lines changed

p2p/net/swarm/dial_error.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ func (e *DialError) recordErr(addr ma.Multiaddr, err error) {
3030
e.Skipped++
3131
return
3232
}
33-
e.DialErrors = append(e.DialErrors, TransportError{
34-
Address: addr,
35-
Cause: err,
36-
})
33+
e.DialErrors = append(e.DialErrors, TransportError{Address: addr, Cause: err})
3734
}
3835

3936
func (e *DialError) Error() string {
@@ -51,9 +48,19 @@ func (e *DialError) Error() string {
5148
return builder.String()
5249
}
5350

54-
// Unwrap implements https://godoc.org/golang.org/x/xerrors#Wrapper.
55-
func (e *DialError) Unwrap() error {
56-
return e.Cause
51+
func (e *DialError) Unwrap() []error {
52+
if e == nil {
53+
return nil
54+
}
55+
56+
errs := make([]error, len(e.DialErrors)+1)
57+
if e.Cause != nil {
58+
errs = append(errs, e.Cause)
59+
}
60+
for i := 0; i < len(e.DialErrors); i++ {
61+
errs = append(errs, &e.DialErrors[i])
62+
}
63+
return errs
5764
}
5865

5966
var _ error = (*DialError)(nil)
@@ -68,4 +75,8 @@ func (e *TransportError) Error() string {
6875
return fmt.Sprintf("failed to dial %s: %s", e.Address, e.Cause)
6976
}
7077

78+
func (e *TransportError) Unwrap() error {
79+
return e.Cause
80+
}
81+
7182
var _ error = (*TransportError)(nil)

p2p/net/swarm/dial_error_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package swarm
2+
3+
import (
4+
"net"
5+
"os"
6+
"testing"
7+
8+
ma "github.com/multiformats/go-multiaddr"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestTransportError(t *testing.T) {
13+
aa := ma.StringCast("/ip4/1.2.3.4/tcp/1234")
14+
te := &TransportError{Address: aa, Cause: ErrDialBackoff}
15+
require.ErrorIs(t, te, ErrDialBackoff, "TransportError should implement Unwrap")
16+
}
17+
18+
func TestDialError(t *testing.T) {
19+
de := &DialError{Peer: "pid", Cause: ErrGaterDisallowedConnection}
20+
require.ErrorIs(t, de, ErrGaterDisallowedConnection,
21+
"DialError Unwrap should handle DialError.Cause")
22+
require.ErrorIs(t, de, de, "DialError Unwrap should handle match to self")
23+
24+
aa := ma.StringCast("/ip4/1.2.3.4/tcp/1234")
25+
ab := ma.StringCast("/ip6/1::1/udp/1234/quic-v1")
26+
de = &DialError{
27+
Peer: "pid",
28+
DialErrors: []TransportError{
29+
{Address: aa, Cause: ErrDialBackoff}, {Address: ab, Cause: ErrNoTransport},
30+
},
31+
}
32+
require.ErrorIs(t, de, ErrDialBackoff, "DialError.Unwrap should traverse TransportErrors")
33+
require.ErrorIs(t, de, ErrNoTransport, "DialError.Unwrap should traverse TransportErrors")
34+
35+
de = &DialError{
36+
Peer: "pid",
37+
DialErrors: []TransportError{{Address: ab, Cause: ErrNoTransport},
38+
// wrapped error 2 levels deep
39+
{Address: aa, Cause: &net.OpError{
40+
Op: "write",
41+
Net: "tcp",
42+
Err: &os.SyscallError{
43+
Syscall: "connect",
44+
Err: os.ErrPermission,
45+
},
46+
}},
47+
},
48+
}
49+
require.ErrorIs(t, de, os.ErrPermission, "DialError.Unwrap should traverse TransportErrors")
50+
51+
}

p2p/net/swarm/swarm_dial_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,5 +372,5 @@ func TestBlackHoledAddrBlocked(t *testing.T) {
372372
if !errors.As(err, &de) {
373373
t.Fatalf("expected to receive an error of type *DialError, got %s of type %T", err, err)
374374
}
375-
require.Contains(t, de.DialErrors, TransportError{Address: addr, Cause: ErrDialRefusedBlackHole})
375+
require.ErrorIs(t, err, ErrDialRefusedBlackHole)
376376
}

0 commit comments

Comments
 (0)