package util import ( "net/http" "runtime" "k8s.io/klog/v2" ) var reallyCrash = true func HandleCrash() { if r := recover(); r != nil { logPanic(r) if reallyCrash { panic(r) } } } // logPanic logs the caller tree when a panic occurs (except in the special case of http.ErrAbortHandler). func logPanic(r interface{}) { if r == http.ErrAbortHandler { // honor the http.ErrAbortHandler sentinel panic value: // ErrAbortHandler is a sentinel panic value to abort a handler. // While any panic from ServeHTTP aborts the response to the client, // panicking with ErrAbortHandler also suppresses logging of a stack trace to the server's error log. return } // Same as stdlib http server code. Manually allocate stack trace buffer size // to prevent excessively large logs const size = 64 << 10 stacktrace := make([]byte, size) stacktrace = stacktrace[:runtime.Stack(stacktrace, false)] if _, ok := r.(string); ok { klog.Errorf("Observed a panic: %s\n%s", r, stacktrace) } else { klog.Errorf("Observed a panic: %#v (%v)\n%s", r, r, stacktrace) } }