Source file
src/net/error_test.go
1
2
3
4
5 package net
6
7 import (
8 "context"
9 "errors"
10 "fmt"
11 "internal/poll"
12 "io"
13 "io/fs"
14 "net/internal/socktest"
15 "os"
16 "runtime"
17 "strings"
18 "testing"
19 "time"
20 )
21
22 func (e *OpError) isValid() error {
23 if e.Op == "" {
24 return fmt.Errorf("OpError.Op is empty: %v", e)
25 }
26 if e.Net == "" {
27 return fmt.Errorf("OpError.Net is empty: %v", e)
28 }
29 for _, addr := range []Addr{e.Source, e.Addr} {
30 switch addr := addr.(type) {
31 case nil:
32 case *TCPAddr:
33 if addr == nil {
34 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
35 }
36 case *UDPAddr:
37 if addr == nil {
38 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
39 }
40 case *IPAddr:
41 if addr == nil {
42 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
43 }
44 case *IPNet:
45 if addr == nil {
46 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
47 }
48 case *UnixAddr:
49 if addr == nil {
50 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
51 }
52 case *pipeAddr:
53 if addr == nil {
54 return fmt.Errorf("OpError.Source or Addr is non-nil interface: %#v, %v", addr, e)
55 }
56 case fileAddr:
57 if addr == "" {
58 return fmt.Errorf("OpError.Source or Addr is empty: %#v, %v", addr, e)
59 }
60 default:
61 return fmt.Errorf("OpError.Source or Addr is unknown type: %T, %v", addr, e)
62 }
63 }
64 if e.Err == nil {
65 return fmt.Errorf("OpError.Err is empty: %v", e)
66 }
67 return nil
68 }
69
70
71
72
73 func parseDialError(nestedErr error) error {
74 if nestedErr == nil {
75 return nil
76 }
77
78 switch err := nestedErr.(type) {
79 case *OpError:
80 if err := err.isValid(); err != nil {
81 return err
82 }
83 nestedErr = err.Err
84 goto second
85 }
86 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
87
88 second:
89 if isPlatformError(nestedErr) {
90 return nil
91 }
92 switch err := nestedErr.(type) {
93 case *AddrError, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError:
94 return nil
95 case interface{ isAddrinfoErrno() }:
96 return nil
97 case *os.SyscallError:
98 nestedErr = err.Err
99 goto third
100 case *fs.PathError:
101 nestedErr = err.Err
102 goto third
103 }
104 switch nestedErr {
105 case errCanceled, ErrClosed, errMissingAddress, errNoSuitableAddress,
106 context.DeadlineExceeded, context.Canceled:
107 return nil
108 }
109 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
110
111 third:
112 if isPlatformError(nestedErr) {
113 return nil
114 }
115 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
116 }
117
118 var dialErrorTests = []struct {
119 network, address string
120 }{
121 {"foo", ""},
122 {"bar", "baz"},
123 {"datakit", "mh/astro/r70"},
124 {"tcp", ""},
125 {"tcp", "127.0.0.1:☺"},
126 {"tcp", "no-such-name:80"},
127 {"tcp", "mh/astro/r70:http"},
128
129 {"tcp", JoinHostPort("127.0.0.1", "-1")},
130 {"tcp", JoinHostPort("127.0.0.1", "123456789")},
131 {"udp", JoinHostPort("127.0.0.1", "-1")},
132 {"udp", JoinHostPort("127.0.0.1", "123456789")},
133 {"ip:icmp", "127.0.0.1"},
134
135 {"unix", "/path/to/somewhere"},
136 {"unixgram", "/path/to/somewhere"},
137 {"unixpacket", "/path/to/somewhere"},
138 }
139
140 func TestDialError(t *testing.T) {
141 switch runtime.GOOS {
142 case "plan9":
143 t.Skipf("%s does not have full support of socktest", runtime.GOOS)
144 }
145
146 origTestHookLookupIP := testHookLookupIP
147 defer func() { testHookLookupIP = origTestHookLookupIP }()
148 testHookLookupIP = func(ctx context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
149 return nil, &DNSError{Err: "dial error test", Name: "name", Server: "server", IsTimeout: true}
150 }
151 sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) {
152 return nil, errOpNotSupported
153 })
154 defer sw.Set(socktest.FilterConnect, nil)
155
156 d := Dialer{Timeout: someTimeout}
157 for i, tt := range dialErrorTests {
158 i, tt := i, tt
159 t.Run(fmt.Sprint(i), func(t *testing.T) {
160 c, err := d.Dial(tt.network, tt.address)
161 if err == nil {
162 t.Errorf("should fail; %s:%s->%s", c.LocalAddr().Network(), c.LocalAddr(), c.RemoteAddr())
163 c.Close()
164 return
165 }
166 if tt.network == "tcp" || tt.network == "udp" {
167 nerr := err
168 if op, ok := nerr.(*OpError); ok {
169 nerr = op.Err
170 }
171 if sys, ok := nerr.(*os.SyscallError); ok {
172 nerr = sys.Err
173 }
174 if nerr == errOpNotSupported {
175 t.Fatalf("should fail without %v; %s:%s->", nerr, tt.network, tt.address)
176 }
177 }
178 if c != nil {
179 t.Errorf("Dial returned non-nil interface %T(%v) with err != nil", c, c)
180 }
181 if err = parseDialError(err); err != nil {
182 t.Error(err)
183 }
184 })
185 }
186 }
187
188 func TestProtocolDialError(t *testing.T) {
189 switch runtime.GOOS {
190 case "solaris", "illumos":
191 t.Skipf("not supported on %s", runtime.GOOS)
192 }
193
194 for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} {
195 var err error
196 switch network {
197 case "tcp":
198 _, err = DialTCP(network, nil, &TCPAddr{Port: 1 << 16})
199 case "udp":
200 _, err = DialUDP(network, nil, &UDPAddr{Port: 1 << 16})
201 case "ip:4294967296":
202 _, err = DialIP(network, nil, nil)
203 case "unix", "unixpacket", "unixgram":
204 _, err = DialUnix(network, nil, &UnixAddr{Name: "//"})
205 }
206 if err == nil {
207 t.Errorf("%s: should fail", network)
208 continue
209 }
210 if err := parseDialError(err); err != nil {
211 t.Errorf("%s: %v", network, err)
212 continue
213 }
214 t.Logf("%s: error as expected: %v", network, err)
215 }
216 }
217
218 func TestDialAddrError(t *testing.T) {
219 switch runtime.GOOS {
220 case "plan9":
221 t.Skipf("not supported on %s", runtime.GOOS)
222 }
223
224 if !supportsIPv4() || !supportsIPv6() {
225 t.Skip("both IPv4 and IPv6 are required")
226 }
227
228 for _, tt := range []struct {
229 network string
230 lit string
231 addr *TCPAddr
232 }{
233 {"tcp4", "::1", nil},
234 {"tcp4", "", &TCPAddr{IP: IPv6loopback}},
235
236
237
238 {"tcp6", "", &TCPAddr{IP: IP{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}}},
239 } {
240 desc := tt.lit
241 if desc == "" {
242 desc = tt.addr.String()
243 }
244 t.Run(fmt.Sprintf("%s/%s", tt.network, desc), func(t *testing.T) {
245 var err error
246 var c Conn
247 var op string
248 if tt.lit != "" {
249 c, err = Dial(tt.network, JoinHostPort(tt.lit, "0"))
250 op = fmt.Sprintf("Dial(%q, %q)", tt.network, JoinHostPort(tt.lit, "0"))
251 } else {
252 c, err = DialTCP(tt.network, nil, tt.addr)
253 op = fmt.Sprintf("DialTCP(%q, %q)", tt.network, tt.addr)
254 }
255 t.Logf("%s: %v", op, err)
256 if err == nil {
257 c.Close()
258 t.Fatalf("%s succeeded, want error", op)
259 }
260 if perr := parseDialError(err); perr != nil {
261 t.Fatal(perr)
262 }
263 operr := err.(*OpError).Err
264 aerr, ok := operr.(*AddrError)
265 if !ok {
266 t.Fatalf("OpError.Err is %T, want *AddrError", operr)
267 }
268 want := tt.lit
269 if tt.lit == "" {
270 want = tt.addr.IP.String()
271 }
272 if aerr.Addr != want {
273 t.Errorf("error Addr=%q, want %q", aerr.Addr, want)
274 }
275 })
276 }
277 }
278
279 var listenErrorTests = []struct {
280 network, address string
281 }{
282 {"foo", ""},
283 {"bar", "baz"},
284 {"datakit", "mh/astro/r70"},
285 {"tcp", "127.0.0.1:☺"},
286 {"tcp", "no-such-name:80"},
287 {"tcp", "mh/astro/r70:http"},
288
289 {"tcp", JoinHostPort("127.0.0.1", "-1")},
290 {"tcp", JoinHostPort("127.0.0.1", "123456789")},
291
292 {"unix", "/path/to/somewhere"},
293 {"unixpacket", "/path/to/somewhere"},
294 }
295
296 func TestListenError(t *testing.T) {
297 switch runtime.GOOS {
298 case "plan9":
299 t.Skipf("%s does not have full support of socktest", runtime.GOOS)
300 }
301
302 origTestHookLookupIP := testHookLookupIP
303 defer func() { testHookLookupIP = origTestHookLookupIP }()
304 testHookLookupIP = func(_ context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
305 return nil, &DNSError{Err: "listen error test", Name: "name", Server: "server", IsTimeout: true}
306 }
307 sw.Set(socktest.FilterListen, func(so *socktest.Status) (socktest.AfterFilter, error) {
308 return nil, errOpNotSupported
309 })
310 defer sw.Set(socktest.FilterListen, nil)
311
312 for i, tt := range listenErrorTests {
313 t.Run(fmt.Sprintf("%s_%s", tt.network, tt.address), func(t *testing.T) {
314 ln, err := Listen(tt.network, tt.address)
315 if err == nil {
316 t.Errorf("#%d: should fail; %s:%s->", i, ln.Addr().Network(), ln.Addr())
317 ln.Close()
318 return
319 }
320 if tt.network == "tcp" {
321 nerr := err
322 if op, ok := nerr.(*OpError); ok {
323 nerr = op.Err
324 }
325 if sys, ok := nerr.(*os.SyscallError); ok {
326 nerr = sys.Err
327 }
328 if nerr == errOpNotSupported {
329 t.Fatalf("#%d: should fail without %v; %s:%s->", i, nerr, tt.network, tt.address)
330 }
331 }
332 if ln != nil {
333 t.Errorf("Listen returned non-nil interface %T(%v) with err != nil", ln, ln)
334 }
335 if err = parseDialError(err); err != nil {
336 t.Errorf("#%d: %v", i, err)
337 }
338 })
339 }
340 }
341
342 var listenPacketErrorTests = []struct {
343 network, address string
344 }{
345 {"foo", ""},
346 {"bar", "baz"},
347 {"datakit", "mh/astro/r70"},
348 {"udp", "127.0.0.1:☺"},
349 {"udp", "no-such-name:80"},
350 {"udp", "mh/astro/r70:http"},
351
352 {"udp", JoinHostPort("127.0.0.1", "-1")},
353 {"udp", JoinHostPort("127.0.0.1", "123456789")},
354 }
355
356 func TestListenPacketError(t *testing.T) {
357 switch runtime.GOOS {
358 case "plan9":
359 t.Skipf("%s does not have full support of socktest", runtime.GOOS)
360 }
361
362 origTestHookLookupIP := testHookLookupIP
363 defer func() { testHookLookupIP = origTestHookLookupIP }()
364 testHookLookupIP = func(_ context.Context, fn func(context.Context, string, string) ([]IPAddr, error), network, host string) ([]IPAddr, error) {
365 return nil, &DNSError{Err: "listen error test", Name: "name", Server: "server", IsTimeout: true}
366 }
367
368 for i, tt := range listenPacketErrorTests {
369 t.Run(fmt.Sprintf("%s_%s", tt.network, tt.address), func(t *testing.T) {
370 c, err := ListenPacket(tt.network, tt.address)
371 if err == nil {
372 t.Errorf("#%d: should fail; %s:%s->", i, c.LocalAddr().Network(), c.LocalAddr())
373 c.Close()
374 return
375 }
376 if c != nil {
377 t.Errorf("ListenPacket returned non-nil interface %T(%v) with err != nil", c, c)
378 }
379 if err = parseDialError(err); err != nil {
380 t.Errorf("#%d: %v", i, err)
381 }
382 })
383 }
384 }
385
386 func TestProtocolListenError(t *testing.T) {
387 switch runtime.GOOS {
388 case "plan9":
389 t.Skipf("not supported on %s", runtime.GOOS)
390 }
391
392 for _, network := range []string{"tcp", "udp", "ip:4294967296", "unix", "unixpacket", "unixgram"} {
393 var err error
394 switch network {
395 case "tcp":
396 _, err = ListenTCP(network, &TCPAddr{Port: 1 << 16})
397 case "udp":
398 _, err = ListenUDP(network, &UDPAddr{Port: 1 << 16})
399 case "ip:4294967296":
400 _, err = ListenIP(network, nil)
401 case "unix", "unixpacket":
402 _, err = ListenUnix(network, &UnixAddr{Name: "//"})
403 case "unixgram":
404 _, err = ListenUnixgram(network, &UnixAddr{Name: "//"})
405 }
406 if err == nil {
407 t.Errorf("%s: should fail", network)
408 continue
409 }
410 if err = parseDialError(err); err != nil {
411 t.Errorf("%s: %v", network, err)
412 continue
413 }
414 }
415 }
416
417
418
419
420 func parseReadError(nestedErr error) error {
421 if nestedErr == nil {
422 return nil
423 }
424
425 switch err := nestedErr.(type) {
426 case *OpError:
427 if err := err.isValid(); err != nil {
428 return err
429 }
430 nestedErr = err.Err
431 goto second
432 }
433 if nestedErr == io.EOF {
434 return nil
435 }
436 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
437
438 second:
439 if isPlatformError(nestedErr) {
440 return nil
441 }
442 switch err := nestedErr.(type) {
443 case *os.SyscallError:
444 nestedErr = err.Err
445 goto third
446 }
447 switch nestedErr {
448 case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
449 return nil
450 }
451 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
452
453 third:
454 if isPlatformError(nestedErr) {
455 return nil
456 }
457 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
458 }
459
460
461
462
463 func parseWriteError(nestedErr error) error {
464 if nestedErr == nil {
465 return nil
466 }
467
468 switch err := nestedErr.(type) {
469 case *OpError:
470 if err := err.isValid(); err != nil {
471 return err
472 }
473 nestedErr = err.Err
474 goto second
475 }
476 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
477
478 second:
479 if isPlatformError(nestedErr) {
480 return nil
481 }
482 switch err := nestedErr.(type) {
483 case *AddrError, *timeoutError, *DNSError, InvalidAddrError, *ParseError, *poll.DeadlineExceededError, UnknownNetworkError:
484 return nil
485 case interface{ isAddrinfoErrno() }:
486 return nil
487 case *os.SyscallError:
488 nestedErr = err.Err
489 goto third
490 }
491 switch nestedErr {
492 case errCanceled, ErrClosed, errMissingAddress, errTimeout, os.ErrDeadlineExceeded, ErrWriteToConnected, io.ErrUnexpectedEOF:
493 return nil
494 }
495 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
496
497 third:
498 if isPlatformError(nestedErr) {
499 return nil
500 }
501 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
502 }
503
504
505
506
507 func parseCloseError(nestedErr error, isShutdown bool) error {
508 if nestedErr == nil {
509 return nil
510 }
511
512
513
514
515
516
517 want := "use of closed network connection"
518 if !isShutdown && !strings.Contains(nestedErr.Error(), want) {
519 return fmt.Errorf("error string %q does not contain expected string %q", nestedErr, want)
520 }
521
522 if !isShutdown && !errors.Is(nestedErr, ErrClosed) {
523 return fmt.Errorf("errors.Is(%v, errClosed) returns false, want true", nestedErr)
524 }
525
526 switch err := nestedErr.(type) {
527 case *OpError:
528 if err := err.isValid(); err != nil {
529 return err
530 }
531 nestedErr = err.Err
532 goto second
533 }
534 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
535
536 second:
537 if isPlatformError(nestedErr) {
538 return nil
539 }
540 switch err := nestedErr.(type) {
541 case *os.SyscallError:
542 nestedErr = err.Err
543 goto third
544 case *fs.PathError:
545 nestedErr = err.Err
546 goto third
547 }
548 switch nestedErr {
549 case ErrClosed:
550 return nil
551 }
552 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
553
554 third:
555 if isPlatformError(nestedErr) {
556 return nil
557 }
558 switch nestedErr {
559 case fs.ErrClosed:
560 return nil
561 }
562 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
563 }
564
565 func TestCloseError(t *testing.T) {
566 t.Run("tcp", func(t *testing.T) {
567 ln := newLocalListener(t, "tcp")
568 defer ln.Close()
569 c, err := Dial(ln.Addr().Network(), ln.Addr().String())
570 if err != nil {
571 t.Fatal(err)
572 }
573 defer c.Close()
574
575 for i := 0; i < 3; i++ {
576 err = c.(*TCPConn).CloseRead()
577 if perr := parseCloseError(err, true); perr != nil {
578 t.Errorf("#%d: %v", i, perr)
579 }
580 }
581 for i := 0; i < 3; i++ {
582 err = c.(*TCPConn).CloseWrite()
583 if perr := parseCloseError(err, true); perr != nil {
584 t.Errorf("#%d: %v", i, perr)
585 }
586 }
587 for i := 0; i < 3; i++ {
588 err = c.Close()
589 if perr := parseCloseError(err, false); perr != nil {
590 t.Errorf("#%d: %v", i, perr)
591 }
592 err = ln.Close()
593 if perr := parseCloseError(err, false); perr != nil {
594 t.Errorf("#%d: %v", i, perr)
595 }
596 }
597 })
598
599 t.Run("udp", func(t *testing.T) {
600 if !testableNetwork("udp") {
601 t.Skipf("skipping: udp not available")
602 }
603
604 pc, err := ListenPacket("udp", "127.0.0.1:0")
605 if err != nil {
606 t.Fatal(err)
607 }
608 defer pc.Close()
609
610 for i := 0; i < 3; i++ {
611 err = pc.Close()
612 if perr := parseCloseError(err, false); perr != nil {
613 t.Errorf("#%d: %v", i, perr)
614 }
615 }
616 })
617 }
618
619
620
621
622 func parseAcceptError(nestedErr error) error {
623 if nestedErr == nil {
624 return nil
625 }
626
627 switch err := nestedErr.(type) {
628 case *OpError:
629 if err := err.isValid(); err != nil {
630 return err
631 }
632 nestedErr = err.Err
633 goto second
634 }
635 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
636
637 second:
638 if isPlatformError(nestedErr) {
639 return nil
640 }
641 switch err := nestedErr.(type) {
642 case *os.SyscallError:
643 nestedErr = err.Err
644 goto third
645 case *fs.PathError:
646 nestedErr = err.Err
647 goto third
648 }
649 switch nestedErr {
650 case ErrClosed, errTimeout, poll.ErrNotPollable, os.ErrDeadlineExceeded:
651 return nil
652 }
653 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
654
655 third:
656 if isPlatformError(nestedErr) {
657 return nil
658 }
659 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
660 }
661
662 func TestAcceptError(t *testing.T) {
663 handler := func(ls *localServer, ln Listener) {
664 for {
665 ln.(*TCPListener).SetDeadline(time.Now().Add(5 * time.Millisecond))
666 c, err := ln.Accept()
667 if perr := parseAcceptError(err); perr != nil {
668 t.Error(perr)
669 }
670 if err != nil {
671 if c != nil {
672 t.Errorf("Accept returned non-nil interface %T(%v) with err != nil", c, c)
673 }
674 if nerr, ok := err.(Error); !ok || (!nerr.Timeout() && !nerr.Temporary()) {
675 return
676 }
677 continue
678 }
679 c.Close()
680 }
681 }
682 ls := newLocalServer(t, "tcp")
683 if err := ls.buildup(handler); err != nil {
684 ls.teardown()
685 t.Fatal(err)
686 }
687
688 time.Sleep(100 * time.Millisecond)
689 ls.teardown()
690 }
691
692
693
694
695 func parseCommonError(nestedErr error) error {
696 if nestedErr == nil {
697 return nil
698 }
699
700 switch err := nestedErr.(type) {
701 case *OpError:
702 if err := err.isValid(); err != nil {
703 return err
704 }
705 nestedErr = err.Err
706 goto second
707 }
708 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
709
710 second:
711 if isPlatformError(nestedErr) {
712 return nil
713 }
714 switch err := nestedErr.(type) {
715 case *os.SyscallError:
716 nestedErr = err.Err
717 goto third
718 case *os.LinkError:
719 nestedErr = err.Err
720 goto third
721 case *fs.PathError:
722 nestedErr = err.Err
723 goto third
724 }
725 switch nestedErr {
726 case ErrClosed:
727 return nil
728 }
729 return fmt.Errorf("unexpected type on 2nd nested level: %T", nestedErr)
730
731 third:
732 if isPlatformError(nestedErr) {
733 return nil
734 }
735 return fmt.Errorf("unexpected type on 3rd nested level: %T", nestedErr)
736 }
737
738 func TestFileError(t *testing.T) {
739 switch runtime.GOOS {
740 case "windows":
741 t.Skipf("not supported on %s", runtime.GOOS)
742 }
743
744 f, err := os.CreateTemp("", "go-nettest")
745 if err != nil {
746 t.Fatal(err)
747 }
748 defer os.Remove(f.Name())
749 defer f.Close()
750
751 c, err := FileConn(f)
752 if err != nil {
753 if c != nil {
754 t.Errorf("FileConn returned non-nil interface %T(%v) with err != nil", c, c)
755 }
756 if perr := parseCommonError(err); perr != nil {
757 t.Error(perr)
758 }
759 } else {
760 c.Close()
761 t.Error("should fail")
762 }
763 ln, err := FileListener(f)
764 if err != nil {
765 if ln != nil {
766 t.Errorf("FileListener returned non-nil interface %T(%v) with err != nil", ln, ln)
767 }
768 if perr := parseCommonError(err); perr != nil {
769 t.Error(perr)
770 }
771 } else {
772 ln.Close()
773 t.Error("should fail")
774 }
775 pc, err := FilePacketConn(f)
776 if err != nil {
777 if pc != nil {
778 t.Errorf("FilePacketConn returned non-nil interface %T(%v) with err != nil", pc, pc)
779 }
780 if perr := parseCommonError(err); perr != nil {
781 t.Error(perr)
782 }
783 } else {
784 pc.Close()
785 t.Error("should fail")
786 }
787
788 ln = newLocalListener(t, "tcp")
789
790 for i := 0; i < 3; i++ {
791 f, err := ln.(*TCPListener).File()
792 if err != nil {
793 if perr := parseCommonError(err); perr != nil {
794 t.Error(perr)
795 }
796 } else {
797 f.Close()
798 }
799 ln.Close()
800 }
801 }
802
803 func parseLookupPortError(nestedErr error) error {
804 if nestedErr == nil {
805 return nil
806 }
807
808 switch nestedErr.(type) {
809 case *AddrError, *DNSError:
810 return nil
811 case *fs.PathError:
812 return nil
813 }
814 return fmt.Errorf("unexpected type on 1st nested level: %T", nestedErr)
815 }
816
817 func TestContextError(t *testing.T) {
818 if !errors.Is(errCanceled, context.Canceled) {
819 t.Error("errCanceled is not context.Canceled")
820 }
821 if !errors.Is(errTimeout, context.DeadlineExceeded) {
822 t.Error("errTimeout is not context.DeadlineExceeded")
823 }
824 }
825
View as plain text