From 31a32d7e14c929ce97cfd4651c4c3b4ecd754ee6 Mon Sep 17 00:00:00 2001 From: Levi Date: Fri, 15 Dec 2023 19:20:56 +0800 Subject: [PATCH] fix: handle api panic (#302) --- pkg/download/downloader.go | 3 +++ pkg/download/extension.go | 8 ++++---- pkg/rest/server.go | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/pkg/download/downloader.go b/pkg/download/downloader.go index 5da0e70e..cfdb5e78 100644 --- a/pkg/download/downloader.go +++ b/pkg/download/downloader.go @@ -8,6 +8,8 @@ import ( "github.com/GopeedLab/gopeed/pkg/base" "github.com/GopeedLab/gopeed/pkg/util" gonanoid "github.com/matoous/go-nanoid/v2" + "github.com/rs/zerolog" + "github.com/rs/zerolog/pkgerrors" "github.com/virtuald/go-paniclog" "os" "path/filepath" @@ -91,6 +93,7 @@ func NewDownloader(cfg *DownloaderConfig) *Downloader { } } + zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack d.Logger = logger.NewLogger(cfg.ProductionMode, filepath.Join(cfg.StorageDir, "logs", "core.log")) d.ExtensionLogger = logger.NewLogger(cfg.ProductionMode, filepath.Join(cfg.StorageDir, "logs", "extension.log")) if cfg.ProductionMode { diff --git a/pkg/download/extension.go b/pkg/download/extension.go index 71218987..262bc559 100644 --- a/pkg/download/extension.go +++ b/pkg/download/extension.go @@ -254,12 +254,12 @@ func (d *Downloader) triggerOnResolve(req *base.Request) (res *base.Resource, er gopeed.Logger.logger.Warn().Err(err).Msgf("[%s] resource invalid", ext.buildIdentity()) return } + ctx.Res.Name = util.ReplaceInvalidFilename(ctx.Res.Name) + for _, file := range ctx.Res.Files { + file.Name = util.ReplaceInvalidFilename(file.Name) + } ctx.Res.CalcSize(nil) } - ctx.Res.Name = util.ReplaceInvalidFilename(ctx.Res.Name) - for _, file := range ctx.Res.Files { - file.Name = util.ReplaceInvalidFilename(file.Name) - } res = ctx.Res }, ) diff --git a/pkg/rest/server.go b/pkg/rest/server.go index 695706d5..9f199027 100644 --- a/pkg/rest/server.go +++ b/pkg/rest/server.go @@ -3,11 +3,13 @@ package rest import ( "context" "encoding/json" + "fmt" "github.com/GopeedLab/gopeed/pkg/download" "github.com/GopeedLab/gopeed/pkg/rest/model" "github.com/GopeedLab/gopeed/pkg/util" "github.com/gorilla/handlers" "github.com/gorilla/mux" + "github.com/pkg/errors" "net" "net/http" "os" @@ -131,6 +133,20 @@ func BuildServer(startCfg *model.StartConfig) (*http.Server, net.Listener, error }) } + // recover panic + r.Use(func(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer func() { + if v := recover(); v != nil { + err := errors.WithStack(fmt.Errorf("%v", v)) + Downloader.Logger.Error().Stack().Err(err).Msg("http server panic") + WriteJson(w, model.NewErrorResult(err.Error(), model.CodeError)) + } + }() + h.ServeHTTP(w, r) + }) + }) + srv = &http.Server{Handler: handlers.CORS( handlers.AllowedHeaders([]string{"Content-Type", "X-Api-Token", "X-Target-Uri"}), handlers.AllowedMethods([]string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"}),