Go 程式中的通用恐慌恢復
在使用Go 程式時,可能存在您想要捕捉並處理崩潰或恐慌的情況它們內部發生的事件,可能用於向Sentry 或Raygun 等錯誤報告伺服器報告。然而,需要注意的是,一個 Goroutine 無法從另一個 Goroutine 的恐慌中恢復。
慣用方法
處理這個問題的慣用方法是將程式碼注入到作為 goroutine 啟動的函數。這涉及到利用一個呼叫recover()的延遲函數,它提供了從恐慌狀態恢復的能力。
考慮以下範例:
go func() { defer func() { if r := recover(); r != nil { fmt.Println("Caught:", r) } }() panic("catch me") }()
此程式碼將輸出相關的恐慌
雖然在您啟動的每個goroutine 中實現這種方法是不切實際的,但您可以透過定義一個命名函數來簡化該過程包括恢復功能,並在您的goroutine 中呼叫該函數(透過延遲呼叫)。
func logger() { if r := recover(); r != nil { fmt.Println("Caught:", r) } }
透過在延遲閉包中呼叫此函數,您可以以簡潔的方式處理恐慌情況。
go func() { defer logger() panic("catch me") }()
包裝器函數
為了更方便,您可以建立一個包裝器將實際函數作為輸入並管理緊急復原過程的函數。此包裝器函數可以如下使用:
func wrap(f func()) { defer func() { if r := recover(); r != nil { fmt.Println("Caught:", r) } }() f() }
使用此包裝器可以進一步簡化恐慌處理過程:
go wrap(func() { panic("catch me") })
其他注意事項
其他注意事項其他注意事項其他注意事項其他注意事項其他注意事項提供的範例程式碼示範了在wrap()函數中啟動goroutine的情況。這允許呼叫者透過在wrapp()呼叫之前加上go關鍵字來確定是否需要一個新的goroutine。然而,wrap() 函數也可用於保護作為輸入傳遞的任意函數的執行,即使您不想在新的 goroutine 中同時運行它們。以上是如何從 Go Goroutine 的恐慌中恢復?的詳細內容。更多資訊請關注PHP中文網其他相關文章!