From f9f5fe436aa870a847c245751b43ed89f18e3353 Mon Sep 17 00:00:00 2001 From: Ta-Ching Chen Date: Thu, 27 Dec 2018 00:14:22 +0800 Subject: [PATCH] Fix go env panic when failed at loading plugin (#1031) Fix go env panic when failed at loading plugin to make it easier for troubleshooting. --- environments/go/server.go | 69 +++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/environments/go/server.go b/environments/go/server.go index 3a803980..0e02456c 100644 --- a/environments/go/server.go +++ b/environments/go/server.go @@ -2,13 +2,15 @@ package main import ( "encoding/json" - "fmt" "io/ioutil" + "log" "net/http" "os" "path/filepath" "plugin" + "github.com/pkg/errors" + "github.com/fission/fission/environments/go/context" ) @@ -37,47 +39,47 @@ type ( var userFunc http.HandlerFunc -func loadPlugin(codePath, entrypoint string) http.HandlerFunc { +func loadPlugin(codePath, entrypoint string) (http.HandlerFunc, error) { // if codepath's a directory, load the file inside it info, err := os.Stat(codePath) if err != nil { - panic(err) + return nil, errors.Wrap(err, "error checking plugin path") } if info.IsDir() { files, err := ioutil.ReadDir(codePath) if err != nil { - panic(err) + return nil, errors.Wrap(err, "error reading directory") } if len(files) == 0 { - panic("No files to load") + return nil, errors.New("No files to load") } fi := files[0] codePath = filepath.Join(codePath, fi.Name()) } - fmt.Printf("loading plugin from %v\n", codePath) + log.Printf("loading plugin from %v\n", codePath) p, err := plugin.Open(codePath) if err != nil { - panic(err) + return nil, errors.Wrap(err, "error loading plugin") } sym, err := p.Lookup(entrypoint) if err != nil { - panic("Entry point not found") + return nil, errors.Wrap(err, "entry point not found") } switch h := sym.(type) { case *http.Handler: - return (*h).ServeHTTP + return (*h).ServeHTTP, nil case *http.HandlerFunc: - return *h + return *h, nil case func(http.ResponseWriter, *http.Request): - return h + return h, nil case func(context.Context, http.ResponseWriter, *http.Request): return func(w http.ResponseWriter, r *http.Request) { c := context.New() h(c, w, r) - } + }, nil default: panic("Entry point not found: bad type") } @@ -94,16 +96,28 @@ func specializeHandler(w http.ResponseWriter, r *http.Request) { if err != nil { if os.IsNotExist(err) { w.WriteHeader(http.StatusNotFound) + log.Printf(err.Error()) w.Write([]byte(CODE_PATH + ": not found")) return } else { - panic(err) + err = errors.Wrap(err, "unknown error") + log.Printf(err.Error()) + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return } } - fmt.Println("Specializing ...") - userFunc = loadPlugin(CODE_PATH, "Handler") - fmt.Println("Done") + log.Println("Specializing ...") + userFunc, err = loadPlugin(CODE_PATH, "Handler") + if err != nil { + err = errors.Wrap(err, "error specializing function") + log.Printf(err.Error()) + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + log.Println("Done") } func specializeHandlerV2(w http.ResponseWriter, r *http.Request) { @@ -115,6 +129,7 @@ func specializeHandlerV2(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil { + log.Println(err.Error()) w.WriteHeader(http.StatusInternalServerError) return } @@ -129,16 +144,28 @@ func specializeHandlerV2(w http.ResponseWriter, r *http.Request) { if err != nil { if os.IsNotExist(err) { w.WriteHeader(http.StatusNotFound) + log.Printf(err.Error()) w.Write([]byte(CODE_PATH + ": not found")) return } else { - panic(err) + err = errors.Wrap(err, "unknown error") + log.Printf(err.Error()) + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return } } - fmt.Println("Specializing ...") - userFunc = loadPlugin(loadreq.FilePath, loadreq.FunctionName) - fmt.Println("Done") + log.Println("Specializing ...") + userFunc, err = loadPlugin(loadreq.FilePath, loadreq.FunctionName) + if err != nil { + err = errors.Wrap(err, "error specializing function") + log.Printf(err.Error()) + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(err.Error())) + return + } + log.Println("Done") } func readinessProbeHandler(w http.ResponseWriter, r *http.Request) { @@ -160,6 +187,6 @@ func main() { userFunc(w, r) }) - fmt.Println("Listening on 8888 ...") + log.Println("Listening on 8888 ...") http.ListenAndServe(":8888", nil) }