Интерфейс net.Error

Интерфейс net.Error представляет сетевую ошибку и расширяет стандартный интерфейс error. Он добавляет метод Timeout, который позволяет определить, является ли ошибка временной и может ли повторный запрос быть успешным. Этот интерфейс реализуется многими типами ошибок в пакете net, такими как OpError, DNSError и AddrError.

Синтаксис

gotype Error interface {
  error
  Timeout() bool
  Temporary() bool
}

Интерфейс содержит три метода: Error возвращает строковое описание ошибки, Timeout сообщает, произошла ли ошибка из-за превышения времени ожидания, а Temporary указывает, является ли ошибка временной и может ли повториться.

Пример sect

Давайте проверим, является ли ошибка временной при попытке подключения к недоступному порту:

gopackage main

import (
  "fmt"
  "net"
  "time"
)

func main() {
  conn, err := net.Dial("tcp", "localhost:9999")
  if err != nil {
    if netErr, ok := err.(net.Error); ok {
      fmt.Println("Is timeout:", netErr.Timeout())
      fmt.Println("Is temporary:", netErr.Temporary())
    }
    fmt.Println("Error:", err)
    return
  }
  defer conn.Close()
  fmt.Println("Connected successfully")
}

Результат выполнения кода:

go"Is timeout: false"
"Is temporary: false"
"Error: dial tcp 127.0.0.1:9999: connect: connection refused"

В этом примере подключение отклонено, поэтому ошибка не является временной.

Пример sect

Рассмотрим пример с установкой времени ожидания для подключения:

gopackage main

import (
  "fmt"
  "net"
  "time"
)

func main() {
  conn, err := net.DialTimeout("tcp", "192.0.2.1:80", 2*time.Second)
  if err != nil {
    if netErr, ok := err.(net.Error); ok {
      fmt.Println("Is timeout:", netErr.Timeout())
      fmt.Println("Is temporary:", netErr.Temporary())
    }
    fmt.Println("Error:", err)
    return
  }
  defer conn.Close()
  fmt.Println("Connected successfully")
}

Результат выполнения кода:

go"Is timeout: true"
"Is temporary: true"
"Error: dial tcp 192.0.2.1:80: i/o timeout"

Здесь ошибка вызвана превышением времени ожидания, поэтому оба метода возвращают true.

Пример sect

Проверим ошибку DNS при попытке разрешить несуществующее имя хоста:

gopackage main

import (
  "fmt"
  "net"
)

func main() {
  ips, err := net.LookupIP("nonexistent.domain.local")
  if err != nil {
    if netErr, ok := err.(net.Error); ok {
      fmt.Println("Is timeout:", netErr.Timeout())
      fmt.Println("Is temporary:", netErr.Temporary())
      fmt.Println("Error type:", fmt.Sprintf("%T", err))
    }
    fmt.Println("Error:", err)
    return
  }
  fmt.Println("IP addresses:", ips)
}

Результат выполнения кода:

go"Is timeout: false"
"Is temporary: false"
"Error type: *net.DNSError"
"Error: lookup nonexistent.domain.local: no such host"

Ошибка DNS не является временной и не связана с таймаутом.

Смотрите также

  • тип net.OpError,
    который представляет ошибки операций ввода-вывода
  • тип net.DNSError,
    который представляет ошибки разрешения DNS
  • тип net.AddrError,
    который представляет ошибки адресации
  • функцию net.DialTimeout,
    которая выполняет подключение с таймаутом