// 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 }