85 lines
2.6 KiB
Go
85 lines
2.6 KiB
Go
// Package cylogger provides panic recovery and safe goroutine execution utilities.
|
|
// These functions help prevent panics from crashing your application by catching
|
|
// them and logging them appropriately.
|
|
package cylogger
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime/debug"
|
|
)
|
|
|
|
// PanicHandler handles a panic and logs it with goroutine ID and stack trace.
|
|
// This function should be used with defer to catch panics in goroutines or functions.
|
|
// When a panic occurs, it logs the panic value, goroutine ID, and full stack trace.
|
|
// Example:
|
|
//
|
|
// defer cylogger.PanicHandler()
|
|
// // Your code that might panic
|
|
func PanicHandler() {
|
|
if r := recover(); r != nil {
|
|
goroutineID := GetGoroutineID()
|
|
stackTrace := debug.Stack()
|
|
Error("PANIC in goroutine %s: %v\n%s", goroutineID, r, stackTrace)
|
|
}
|
|
}
|
|
|
|
// SafeGo launches a goroutine with panic recovery.
|
|
// If the goroutine panics, the panic will be caught and logged instead of crashing the program.
|
|
// This is useful for running potentially unstable code in goroutines.
|
|
// Usage: cylogger.SafeGo(func() { ... your code ... })
|
|
// Example:
|
|
//
|
|
// cylogger.SafeGo(func() {
|
|
// // Code that might panic
|
|
// riskyOperation()
|
|
// })
|
|
func SafeGo(f func()) {
|
|
go func() {
|
|
defer PanicHandler()
|
|
f()
|
|
}()
|
|
}
|
|
|
|
// SafeGoWithArgs launches a goroutine with panic recovery and passes arguments.
|
|
// If the goroutine panics, the panic will be caught and logged instead of crashing the program.
|
|
// This is useful for running potentially unstable code in goroutines with specific arguments.
|
|
// Usage: cylogger.SafeGoWithArgs(func(arg1, arg2 interface{}) { ... }, "value1", 42)
|
|
// Example:
|
|
//
|
|
// cylogger.SafeGoWithArgs(func(args ...interface{}) {
|
|
// // Code that might panic with arguments
|
|
// processData(args[0], args[1])
|
|
// }, "data1", 42)
|
|
func SafeGoWithArgs(f func(...interface{}), args ...interface{}) {
|
|
go func() {
|
|
defer PanicHandler()
|
|
f(args...)
|
|
}()
|
|
}
|
|
|
|
// SafeExec executes a function with panic recovery and returns an error if a panic occurs.
|
|
// This is useful for code that should not panic but might, allowing you to handle panics gracefully.
|
|
// If the function panics, it returns an error describing the panic instead of crashing the program.
|
|
// Example:
|
|
//
|
|
// err := cylogger.SafeExec(func() {
|
|
// // Code that might panic
|
|
// riskyOperation()
|
|
// })
|
|
// if err != nil {
|
|
// // Handle the panic as an error
|
|
// }
|
|
func SafeExec(f func()) (err error) {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
goroutineID := GetGoroutineID()
|
|
stackTrace := debug.Stack()
|
|
Error("PANIC in goroutine %s: %v\n%s", goroutineID, r, stackTrace)
|
|
err = fmt.Errorf("panic recovered: %v", r)
|
|
}
|
|
}()
|
|
|
|
f()
|
|
return nil
|
|
}
|