建議每起一個goroutine,都defer統(tǒng)一捕獲下異常
之前的代碼是這樣的纷闺,想在main函數(shù)統(tǒng)一捕獲所有的異常(包括協(xié)程的)并輸出到crash.log文件中,但是程序奔潰后crash.log并沒有相應(yīng)的記錄份蝴。(謹(jǐn)記用defer統(tǒng)一捕獲異常只對當(dāng)前的goroutine有效犁功,goroutine的異常并不會向上傳遞給main主函數(shù))
package main
import (
"log"
"os"
"time"
)
var Error *log.Logger
func init() {
errFile, err := os.OpenFile("./crash.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatalln("打開日志文件失敗:", err)
}
Error = log.New(errFile, "Error:", log.Ldate|log.Ltime|log.Lshortfile)
}
func main() {
defer func() {
if err := recover(); err != nil {
Error.Println("程序crash了:", err)
}
}()
go panicFunc()
time.Sleep(time.Second)
}
func panicFunc() {
log.Println("panicFunc 開始運行")
panic("panicFunc崩潰了")
}
后來經(jīng)大神指教婚夫,才明白
func main() {
defer func() {
if err := recover(); err != nil {
Error.Println("程序crash了:", err)
}
}()
//TODO:
}
只捕獲當(dāng)前goroutine拋出的異常鏈浸卦,所以如果要捕獲異常的話,則需要在每個goroutine加defer函數(shù)捕獲異常案糙。明白這一點后限嫌,panicFunc程序則需改為:
func panicFunc() {
defer func() {
if err := recover(); err != nil {
Error.Println(err)
}
}()
log.Println("panicFunc 開始運行")
panic("panicFunc崩潰了")
}