Самый простой способ - просто проверить текст ошибки:
conn, err := net.ListenUDP("udp", addr)
if err != nil && err.Error() == "bind: address already in use" {
// Failed to bind, do something
}
if err != nil {
// Some other error
panic(err)
}
Для такого простого случая, как этот, этого может быть достаточно. Однако этот подход несколько хрупок:
- Если библиотека когда-либо изменит сообщение об ошибке (это время от времени происходит, хотя, вероятно, маловероятно в этом конкретном случае), проверка прервет
- Если вы выполните эту проверку в какой-либо функции переноса, которая также может возвращать другие типы ошибок, вы можете, по крайней мере, теоретически, получить ложное срабатывание, если некоторые другие функции возвращают ошибку с тем же текстом (также, вероятно, маловероятно в данном случае)
Чтобы смягчить эти проблемы, вы можете проверить конкретный тип ошибки, а не просто текстовое представление. В вашем примере пакет net содержит несколько пользовательских ошибок. Метод ListenUDP
возвращает net.OpError
, что означает, что вы можете изучить его более внимательно. Например:
conn, err := net.ListenUDP("udp", addr)
if opErr, ok := err.(*net.OpError); ok {
if opErr.Op == "listen" && strings.Contains(opErr.Error.Error(), "address already in use") {
// Failed to bind, do something
}
}
if err != nil {
// Some other error, panic
panic(err)
}
В этом случае мы по-прежнему зависим от текстовой проверки, поэтому все еще существует риск будущих изменений библиотеки, нарушающих тест. Но проверяя тип net.OpError
, мы уменьшаем второй риск того, что может возникнуть какая-то другая ошибка с тем же текстом.