Skip to content

Commit 4ffeadd

Browse files
committed
feat(generic_http_thrift): fail on nil value for required field
1 parent 4e1dbe9 commit 4ffeadd

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

pkg/generic/thrift/http.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,12 @@ func NewHTTPReaderWriter(svc *descriptor.ServiceDescriptor) *HTTPReaderWriter {
4343

4444
// WriteHTTPRequest implement of MessageWriter
4545
type WriteHTTPRequest struct {
46-
svc *descriptor.ServiceDescriptor
47-
binaryWithBase64 bool
48-
convOpts conv.Options // used for dynamicgo conversion
49-
convOptsWithThriftBase conv.Options // used for dynamicgo conversion with EnableThriftBase turned on
50-
dynamicgoEnabled bool
46+
svc *descriptor.ServiceDescriptor
47+
binaryWithBase64 bool
48+
convOpts conv.Options // used for dynamicgo conversion
49+
convOptsWithThriftBase conv.Options // used for dynamicgo conversion with EnableThriftBase turned on
50+
dynamicgoEnabled bool
51+
failOnNilValueForRequiredField bool // will return error when field is required but input value is nil
5152
}
5253

5354
var (
@@ -71,6 +72,10 @@ func (w *WriteHTTPRequest) SetBinaryWithBase64(enable bool) {
7172
w.binaryWithBase64 = enable
7273
}
7374

75+
func (w *WriteHTTPRequest) SetFailOnNilValueForRequiredField(enable bool) {
76+
w.failOnNilValueForRequiredField = enable
77+
}
78+
7479
// SetDynamicGo ...
7580
func (w *WriteHTTPRequest) SetDynamicGo(convOpts, convOptsWithThriftBase *conv.Options) {
7681
w.convOpts = *convOpts
@@ -94,7 +99,7 @@ func (w *WriteHTTPRequest) originalWrite(ctx context.Context, out bufiox.Writer,
9499
requestBase = nil
95100
}
96101
bw := thrift.NewBufferWriter(out)
97-
err = wrapStructWriter(ctx, req, bw, fn.Request, &writerOption{requestBase: requestBase, binaryWithBase64: w.binaryWithBase64})
102+
err = wrapStructWriter(ctx, req, bw, fn.Request, &writerOption{requestBase: requestBase, binaryWithBase64: w.binaryWithBase64, failOnNilValueForRequiredField: w.failOnNilValueForRequiredField})
98103
bw.Recycle()
99104
return err
100105
}

pkg/generic/thrift/write.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ type writerOption struct {
3535
requestBase *base.Base // request base from metahandler
3636
// decoding Base64 to binary
3737
binaryWithBase64 bool
38+
// will return error when field is required but input value is nil
39+
failOnNilValueForRequiredField bool
3840
}
3941

4042
type writer func(ctx context.Context, val interface{}, out *thrift.BufferWriter, t *descriptor.TypeDescriptor, opt *writerOption) error
@@ -778,6 +780,9 @@ func writeHTTPRequest(ctx context.Context, val interface{}, out *thrift.BufferWr
778780

779781
if v == nil {
780782
if !field.Optional {
783+
if opt != nil && opt.failOnNilValueForRequiredField {
784+
return fmt.Errorf("value of field [%s] is nil", name)
785+
}
781786
if err := out.WriteFieldBegin(field.Type.Type.ToThriftTType(), int16(field.ID)); err != nil {
782787
return err
783788
}

pkg/generic/thrift/write_test.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,36 @@ func Test_writeHTTPRequest(t *testing.T) {
13581358
},
13591359
false,
13601360
},
1361+
{
1362+
"writeStructRequiredFail",
1363+
args{
1364+
val: &descriptor.HTTPRequest{
1365+
Body: map[string]interface{}{"hello": nil},
1366+
},
1367+
1368+
t: &descriptor.TypeDescriptor{
1369+
Type: descriptor.STRUCT,
1370+
Key: &descriptor.TypeDescriptor{Type: descriptor.STRING},
1371+
Elem: &descriptor.TypeDescriptor{Type: descriptor.STRING},
1372+
Struct: &descriptor.StructDescriptor{
1373+
Name: "Demo",
1374+
FieldsByName: map[string]*descriptor.FieldDescriptor{
1375+
"hello": {
1376+
Name: "hello",
1377+
ID: 1,
1378+
Required: true,
1379+
Type: &descriptor.TypeDescriptor{Type: descriptor.STRING},
1380+
HTTPMapping: descriptor.DefaultNewMapping("hello"),
1381+
},
1382+
},
1383+
},
1384+
},
1385+
opt: &writerOption{
1386+
failOnNilValueForRequiredField: true,
1387+
},
1388+
},
1389+
true,
1390+
},
13611391
}
13621392
for _, tt := range tests {
13631393
t.Run(tt.name, func(t *testing.T) {
@@ -1434,7 +1464,7 @@ func getReqPbBody() (proto.Message, error) {
14341464
path := "main.proto"
14351465
content := `
14361466
package kitex.test.server;
1437-
1467+
14381468
message BizReq {
14391469
optional int32 user_id = 1;
14401470
optional string user_name = 2;

0 commit comments

Comments
 (0)