在 Golang 中處理異常

通常我們需要編寫好的錯誤處理方式,在了避免某些程序員濫用異常,於是 Go 這裏直接把異常這一塊給砍掉了,最終還是通過返回值來判斷程序的異常情況,畢竟 Go 可是支持多返回值的語言,比如 atoi、itoa 等函數,就不能忽略它的第二個返回值,因爲第二個返回值代表了轉換是否成功!不過 Golang 還是提供了一些錯誤處理機制的

Go 的錯誤機制

1、沒有異常機制

2、error 類型實現了 error 接口

3、可以通過 errors.New 來快速創建錯誤實例

type error interface{
    Error() string
}

error.New("n must be in range[0, 1]")
複製代碼

但是這樣做只是給開發者標識,Code 怎麼認識呢?難道去 string 裏判斷嗎?當然不是,可以預定義一些錯誤:

處理錯誤最佳實踐

1、預定義錯誤,code 裏判斷

2、及早失敗,避免嵌套

panic 與 recover

panic 用於不可恢復的錯誤,類似於 Java 的 Error

panic 退出前會執行 defer 指定的內容

panic 和 os.Exit

os.Exit 退出時不會調用 defer 指定的函數

os.Exit 退出時不會輸出當前調用棧信息

接下來看看 recover

在 Java 中如果你不知道要拋出什麼錯誤,於是乎很多人直接來個 Catch Throwable,作爲一個異常無 Fack 說,C++ 中是直接 catch… 作爲一個異常無 Fack 說

在 Go 語言中可以通過 defer 定義的函數去執行一些錯誤恢復的行爲

很多人容易在 defer 處理錯誤時把 recover 獲得的錯誤對象打印到日誌文件中,這是一種非常危險的做法,一定要當心 recover 在做的事情,因爲 recover 的時候並不去檢測到底發生了什麼錯誤,而是直接忽略了這個錯誤,那麼如果這個時候系統的核心資源消耗完了,如果我們強制性的恢復的話系統仍然是不能正常工作的,還會導致我們的健康檢查程序沒辦法檢查出當前系統的問題,因爲很多的 health check 只是檢查進程在還是不在,因爲我們的進程是在的,所以會導致殭屍服務進程,雖然活着但是無法正常提供服務。於是我們可以採用恢復設計模式中的一種叫做 Let it Crash ,health check 進程就會幫我們重啓這個服務

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://juejin.cn/post/6970568554689069086