Как определить время ожидания запроса? [Дубликат]

22
задан Martijn van Maasakkers 6 May 2014 в 13:36
поделиться

2 ответа

Начиная с go1.6, все ошибки от тайм-аутов должны соответствовать net.Error, если Timeout() установлен правильно. Все, что вам нужно проверить, это:

if err, ok := err.(net.Error); ok && err.Timeout() {

В старых версиях проверка на таймаут через http-пакет была более сложной.

  • Вы можете получить *net.OpError с Timeout (), если вы нажмете Deadline, установленный в базовом соединении.
  • Вы можете получить tlsHandshakeTimeoutError (который явно не экспортируется), который реализует интерфейс net.Error.
  • Вы можете получить url.Error, если в пакете url возникла проблема (таймаут во время начального соединения)
  • Вы можете получить сообщение об ошибке «использование закрытого сетевого подключения», если вы нажмете тайм-аут с http.Client.Timeout [go1.3 +] (который вызывает Transport.CancelRequest). Начиная с go1.5, это свойство будет правильно установлено свойство Timeout.

Вы можете проверить net.Error с помощью переключателя типа:

switch err := err.(type) {
case net.Error:
    if err.Timeout() {
        fmt.Println("This was a net.Error with a Timeout")
    }
case *url.Error:
    fmt.Println("This is a *url.Error")
    if err, ok := err.Err.(net.Error); ok && err.Timeout() {
        fmt.Println("and it was because of a timeout")
    }
}

С go & lt; 1.5 вам нужно будет проверить строку ошибки для таймаута http.Client:

if err != nil && strings.Contains(err.Error(), "use of closed network connection") {
    fmt.Println("Could be from a Transport.CancelRequest")
}
47
ответ дан JimB 17 August 2018 в 16:11
поделиться
  • 1
    Это прекрасно работает, спасибо! – Martijn van Maasakkers 6 May 2014 в 16:14
  • 2
    Извините, я, вероятно, должен был утверждать net.Error, так как вы могли бы вернуть Timeouts, которые не являются OpError. – JimB 6 May 2014 в 17:17
  • 3
    Итак, с http.Client.Timeout [go1.3 +] невозможно проверить, является ли ошибка таймаутом из Transport.CancelRequest? Есть ли сообщение об ошибке? Для меня сообщение совершенно сбивает с толку. – Kamil Dziedzic 31 March 2015 в 19:02
  • 4

Вы хотите интерфейс net.Error. http://golang.org/pkg/net/#Error

if e,ok := err.(net.Error); ok && e.Timeout() {
    // This was a timeout
} else if err != nil {
    // This was an error, but not a timeout
}

Обратите внимание, что утверждение типа err.(net.Error) корректно обрабатывает случай nil и возвращает false для значения ok, если nil возвращается как ошибка, короткое замыкание проверки Timeout.

14
ответ дан LinearZoetrope 17 August 2018 в 16:11
поделиться
  • 1
    К сожалению, попытка response, err := client.Do(req) if e, ok := err.(net.Error); ok && e.Timeout() { // This was a timeout fmt.Println("timeout") return } ничего мне не дает: S – Martijn van Maasakkers 6 May 2014 в 14:20
  • 2
    Вы уверены, что это ошибка таймаута? вы, вероятно, захотите добавить проверку else if err != nil, чтобы покрыть ошибки, не связанные с таймаутом. – LinearZoetrope 6 May 2014 в 14:26
  • 3
    Я установил таймаут (maxwait) на 2 секунды, а за ним скрипт php где-то со сном 10 секунд (таким образом, это должен быть тайм-аут), возвращенная ошибка: Get api.vagrant / test.php : чтение tcp 192.168.33.10:80: тайм-аут i / o – Martijn van Maasakkers 6 May 2014 в 14:31
  • 4
    Это то, что я делаю: play.golang.org/p/N-fAarjGFx – Martijn van Maasakkers 6 May 2014 в 14:41
  • 5
    Я не уверен, DialTimeout должен возвращать net.Error, если он терпит неудачу. Я пытаюсь прочитать источник пакета net, но, к сожалению, низкоуровневый сетевой код является системным, и, следовательно, немного сложно найти доказательства того, что возвращается, поскольку он похоронен под 30 вызовами функций в разных файлах. – LinearZoetrope 6 May 2014 в 14:53
Другие вопросы по тегам:

Похожие вопросы: