mirror of https://github.com/k3s-io/k3s
90 lines
2.5 KiB
Go
90 lines
2.5 KiB
Go
/*
|
|
Copyright 2014 The Kubernetes Authors All rights reserved.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/golang/glog"
|
|
"runtime"
|
|
)
|
|
|
|
// For testing, bypass HandleCrash.
|
|
var ReallyCrash bool
|
|
|
|
// PanicHandlers is a list of functions which will be invoked when a panic happens.
|
|
var PanicHandlers = []func(interface{}){logPanic}
|
|
|
|
//TODO search the public functions
|
|
// HandleCrash simply catches a crash and logs an error. Meant to be called via defer.
|
|
// Additional context-specific handlers can be provided, and will be called in case of panic
|
|
func HandleCrash(additionalHandlers ...func(interface{})) {
|
|
if ReallyCrash {
|
|
return
|
|
}
|
|
if r := recover(); r != nil {
|
|
for _, fn := range PanicHandlers {
|
|
fn(r)
|
|
}
|
|
for _, fn := range additionalHandlers {
|
|
fn(r)
|
|
}
|
|
}
|
|
}
|
|
|
|
// logPanic logs the caller tree when a panic occurs.
|
|
func logPanic(r interface{}) {
|
|
callers := ""
|
|
for i := 0; true; i++ {
|
|
_, file, line, ok := runtime.Caller(i)
|
|
if !ok {
|
|
break
|
|
}
|
|
callers = callers + fmt.Sprintf("%v:%v\n", file, line)
|
|
}
|
|
glog.Errorf("Recovered from panic: %#v (%v)\n%v", r, r, callers)
|
|
}
|
|
|
|
// ErrorHandlers is a list of functions which will be invoked when an unreturnable
|
|
// error occurs.
|
|
var ErrorHandlers = []func(error){logError}
|
|
|
|
// HandlerError is a method to invoke when a non-user facing piece of code cannot
|
|
// return an error and needs to indicate it has been ignored. Invoking this method
|
|
// is preferable to logging the error - the default behavior is to log but the
|
|
// errors may be sent to a remote server for analysis.
|
|
func HandleError(err error) {
|
|
for _, fn := range ErrorHandlers {
|
|
fn(err)
|
|
}
|
|
}
|
|
|
|
// logError prints an error with the call stack of the location it was reported
|
|
func logError(err error) {
|
|
glog.ErrorDepth(2, err)
|
|
}
|
|
|
|
// GetCaller returns the caller of the function that calls it.
|
|
func GetCaller() string {
|
|
var pc [1]uintptr
|
|
runtime.Callers(3, pc[:])
|
|
f := runtime.FuncForPC(pc[0])
|
|
if f == nil {
|
|
return fmt.Sprintf("Unable to find caller")
|
|
}
|
|
return f.Name()
|
|
}
|