diff --git a/main.go b/main.go index c32b087..f4e4e90 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,4 @@ -package logger +package main import ( "bytes" diff --git a/safe.go b/safe.go new file mode 100644 index 0000000..55a9f1c --- /dev/null +++ b/safe.go @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + "runtime/debug" +) + +// PanicHandler handles a panic and logs it +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 +// Usage: logger.SafeGo(func() { ... your code ... }) +func SafeGo(f func()) { + go func() { + defer PanicHandler() + f() + }() +} + +// SafeGoWithArgs launches a goroutine with panic recovery and passes arguments +// Usage: logger.SafeGoWithArgs(func(arg1, arg2 interface{}) { ... }, "value1", 42) +func SafeGoWithArgs(f func(...interface{}), args ...interface{}) { + go func() { + defer PanicHandler() + f(args...) + }() +} + +// SafeExec executes a function with panic recovery +// Useful for code that should not panic +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 +}