我正在使用的conn.SetReadDeadline方法設定讀取超時conn,當conn.Read等待超過指定時間時,它會回傳并回傳型別的錯誤*net.OpError。net包裝所有非錯誤后,此錯誤由包回傳io.EOF。
我可以在用Unwrap(). 超時錯誤是型別的錯誤*poll.DeadlineExceededError。我在我的代碼中使用這樣的陳述句來精確地處理超時錯誤。
import "internal/poll"
_, err = conn.Read(p)
if err != nil {
if pe, ok := err.(*net.OpError); ok {
err = pe.Unwrap()
if timeout, ok := err.(*poll.DeadlineExceededError); ok {
log.Error(fmt.Sprintf("%T, %s", timeout, timeout))
}
}
return
}
我在運行程式時收到use of internal package internal/poll not allowed錯誤。編譯器告訴我不能使用內部包。
我用谷歌搜索并找到了洗掉internal檔案夾的解決方案,這是最終的解決方案嗎?會有更好的解決方案嗎?
uj5u.com熱心網友回復:
該os包將該錯誤匯出為os.ErrDeadlineExceeded(檢查源代碼)。你可以試試 :
if errors.Is(err, os.ErrDeadlineExceeded) {
log.Error("Timeout error")
}
[編輯]實際上,在閱讀了@Brit 的評論后,這是檢查該錯誤的記錄方法。請參閱檔案Conn.SetDeadline():
如果超過最后期限,對 Read 或 Write 或其他 I/O 方法的呼叫將回傳包裝 os.ErrDeadlineExceeded 的錯誤。這可以使用 errors.Is(err, os.ErrDeadlineExceeded) 進行測驗。
另一個表明錯誤是“超時”錯誤的跡象是它是否有一個Timeout() bool方法,該方法true在呼叫時回傳。
這是net.Error介面的一部分(盡管此介面有一個額外的方法,它被記錄為已棄用),并由net.OpError型別(以及內部poll.DeadlineExceededError型別)實作。
有幾個函式(例如net.OpError.IsTimeout(),os.SyscallError.IsTimeout()和公共函式os.IsTimeout())通過??直接將錯誤值轉換為timeout介面來實作超時檢查。
如果您想處理可以包含在另一個錯誤中的錯誤,您可能希望isTimeout()使用以下方法實作您自己的檢查errors.As(...):
// isTimeout : use errors.As() to unwrap errors and check if a sub error is a Timeout error
func isTimeout(err error) bool {
var terr interface{ Timeout() bool }
return errors.As(err, &terr) && terr.Timeout()
}
https://go.dev/play/p/OhhKY3XsGjZ
注意 :
isTimeout()上面的函式和呼叫之間的區別在于errors.Is(err, os.ErrDeadlineExceeded),后者將嘗試精確匹配一個ErrDeadlineExceeded(這主要是通過設定SetDeadline()一些類似檔案或 conn 的物件來觸發的),而后者可能會為嘗試的錯誤回傳 true出于其他原因宣傳“我是超時錯誤”(例如:HTTP“408 請求超時”回應)
注意:以上所有鏈接均參考 go 1.18.3。根據您使用的 go 版本,您可能需要修改上面的一些代碼(例如:os.ErrDeadlineExceeded在go1.15中添加)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/493502.html
標籤:去
下一篇:為什么我的環境變數顯示為未定義?
