From 9f33fc5c13c5dc460ec7d613f231c4e107a5f46a Mon Sep 17 00:00:00 2001 From: GuangyuFan <97507466+FGYFFFF@users.noreply.github.com> Date: Tue, 11 Jun 2024 15:55:34 +0800 Subject: [PATCH] optimize: non-existent file error for binding (#1135) --- pkg/app/server/binding/binder_test.go | 25 +++++++++++++++++++ .../decoder/multipart_file_decoder.go | 10 +++++--- .../internal/decoder/struct_type_decoder.go | 4 +-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/pkg/app/server/binding/binder_test.go b/pkg/app/server/binding/binder_test.go index ec962dafa..1ea7b1e36 100644 --- a/pkg/app/server/binding/binder_test.go +++ b/pkg/app/server/binding/binder_test.go @@ -692,6 +692,31 @@ func TestBind_FileBind(t *testing.T) { assert.DeepEqual(t, fileName, (**s.D).N.Filename) } +func TestBind_FileBindWithNoFile(t *testing.T) { + var s struct { + A *multipart.FileHeader `file_name:"a"` + B *multipart.FileHeader `form:"b"` + C *multipart.FileHeader + } + fileName := "binder_test.go" + req := newMockRequest(). + SetRequestURI("http://foobar.com"). + SetFile("a", fileName). + SetFile("b", fileName) + // to parse multipart files + req2 := req2.GetHTTP1Request(req.Req) + _ = req2.String() + err := DefaultBinder().Bind(req.Req, &s, nil) + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + assert.DeepEqual(t, fileName, s.A.Filename) + assert.DeepEqual(t, fileName, s.B.Filename) + if s.C != nil { + t.Fatalf("expected a nil for s.C") + } +} + func TestBind_FileSliceBind(t *testing.T) { type Nest struct { N *[]*multipart.FileHeader `form:"b"` diff --git a/pkg/app/server/binding/internal/decoder/multipart_file_decoder.go b/pkg/app/server/binding/internal/decoder/multipart_file_decoder.go index ae32dfea5..b11417728 100644 --- a/pkg/app/server/binding/internal/decoder/multipart_file_decoder.go +++ b/pkg/app/server/binding/internal/decoder/multipart_file_decoder.go @@ -20,6 +20,7 @@ import ( "fmt" "reflect" + "github.com/cloudwego/hertz/pkg/common/hlog" "github.com/cloudwego/hertz/pkg/protocol" "github.com/cloudwego/hertz/pkg/route/param" ) @@ -52,7 +53,8 @@ func (d *fileTypeDecoder) Decode(req *protocol.Request, params param.Params, req } file, err := req.FormFile(fileName) if err != nil { - return fmt.Errorf("can not get file '%s', err: %v", fileName, err) + hlog.SystemLogger().Warnf("can not get file '%s' form request, reason: %v, so skip '%s' field binding", fileName, err, d.fieldName) + return nil } if field.Kind() == reflect.Ptr { t := field.Type() @@ -105,11 +107,13 @@ func (d *fileTypeDecoder) fileSliceDecode(req *protocol.Request, params param.Pa } multipartForm, err := req.MultipartForm() if err != nil { - return fmt.Errorf("can not get multipartForm info, err: %v", err) + hlog.SystemLogger().Warnf("can not get MultipartForm from request, reason: %v, so skip '%s' field binding", fileName, err, d.fieldName) + return nil } files, exist := multipartForm.File[fileName] if !exist { - return fmt.Errorf("the file '%s' is not existed", fileName) + hlog.SystemLogger().Warnf("the file '%s' is not existed in request, so skip '%s' field binding", fileName, d.fieldName) + return nil } if field.Kind() == reflect.Array { diff --git a/pkg/app/server/binding/internal/decoder/struct_type_decoder.go b/pkg/app/server/binding/internal/decoder/struct_type_decoder.go index c2af2c030..4a3ded138 100644 --- a/pkg/app/server/binding/internal/decoder/struct_type_decoder.go +++ b/pkg/app/server/binding/internal/decoder/struct_type_decoder.go @@ -83,7 +83,7 @@ func (d *structTypeFieldTextDecoder) Decode(req *protocol.Request, params param. var vv reflect.Value vv, err := stringToValue(t, text, req, params, d.config) if err != nil { - hlog.Infof("unable to decode '%s' as %s: %v, but it may not affect correctness, so skip it", text, d.fieldType.Name(), err) + hlog.SystemLogger().Infof("unable to decode '%s' as %s: %v, but it may not affect correctness, so skip it", text, d.fieldType.Name(), err) return nil } field.Set(ReferenceValue(vv, ptrDepth)) @@ -92,7 +92,7 @@ func (d *structTypeFieldTextDecoder) Decode(req *protocol.Request, params param. err = hjson.Unmarshal(bytesconv.S2b(text), field.Addr().Interface()) if err != nil { - hlog.Infof("unable to decode '%s' as %s: %v, but it may not affect correctness, so skip it", text, d.fieldType.Name(), err) + hlog.SystemLogger().Infof("unable to decode '%s' as %s: %v, but it may not affect correctness, so skip it", text, d.fieldType.Name(), err) } return nil