Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ecd18128a4 | |||
| f16f5b0116 | |||
| 8291a17aca | |||
| 7ad16974b6 | |||
| 8918f7f891 | |||
| 29a23a75ba | |||
| d9c5d0857b |
+100
-30
@@ -39,7 +39,7 @@ var basicTypes = []string{
|
||||
}
|
||||
|
||||
// Verify whether the parameters meet the requirements
|
||||
var validateParams = []string{"require", "pattern", "maxLength", "minLength", "maximum", "minimum"}
|
||||
var validateParams = []string{"require", "pattern", "maxLength", "minLength", "maximum", "minimum", "maxItems", "minItems"}
|
||||
|
||||
// CastError is used for cast type fails
|
||||
type CastError struct {
|
||||
@@ -71,6 +71,8 @@ type SDKError struct {
|
||||
Code *string
|
||||
Message *string
|
||||
Data *string
|
||||
Stack *string
|
||||
errMsg *string
|
||||
}
|
||||
|
||||
// RuntimeObject is used for converting http configuration
|
||||
@@ -178,6 +180,20 @@ func NewSDKError(obj map[string]interface{}) *SDKError {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set ErrMsg by msg
|
||||
func (err *SDKError) SetErrMsg(msg string) {
|
||||
err.errMsg = String(msg)
|
||||
}
|
||||
|
||||
func (err *SDKError) Error() string {
|
||||
if err.errMsg == nil {
|
||||
str := fmt.Sprintf("SDKError:\n Code: %s\n Message: %s\n Data: %s\n",
|
||||
StringValue(err.Code), StringValue(err.Message), StringValue(err.Data))
|
||||
err.SetErrMsg(str)
|
||||
}
|
||||
return StringValue(err.errMsg)
|
||||
}
|
||||
|
||||
// Return message of CastError
|
||||
func (err *CastError) Error() string {
|
||||
return StringValue(err.Message)
|
||||
@@ -190,6 +206,14 @@ func Convert(in interface{}, out interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert is use convert map[string]interface object to struct
|
||||
func Recover(in interface{}) error {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
return errors.New(fmt.Sprint(in))
|
||||
}
|
||||
|
||||
// ReadBody is used read response body
|
||||
func (response *Response) ReadBody() (body []byte, err error) {
|
||||
defer response.Body.Close()
|
||||
@@ -283,7 +307,7 @@ func DoRequest(request *Request, requestRuntime map[string]interface{}) (respons
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.httpClient.Timeout = time.Duration(IntValue(runtimeObject.ConnectTimeout)) * time.Second
|
||||
client.httpClient.Timeout = time.Duration(IntValue(runtimeObject.ReadTimeout)) * time.Millisecond
|
||||
client.httpClient.Transport = trans
|
||||
client.ifInit = true
|
||||
}
|
||||
@@ -367,7 +391,7 @@ func getHttpTransport(req *Request, runtime *RuntimeObject) (*http.Transport, er
|
||||
}
|
||||
dialer, err := proxy.SOCKS5(strings.ToLower(StringValue(runtime.Socks5NetWork)), socks5Proxy.String(), auth,
|
||||
&net.Dialer{
|
||||
Timeout: time.Duration(IntValue(runtime.ConnectTimeout)) * time.Second,
|
||||
Timeout: time.Duration(IntValue(runtime.ConnectTimeout)) * time.Millisecond,
|
||||
DualStack: true,
|
||||
LocalAddr: getLocalAddr(StringValue(runtime.LocalAddr), IntValue(req.Port)),
|
||||
})
|
||||
@@ -495,11 +519,6 @@ func setDialContext(runtime *RuntimeObject, port int) func(cxt context.Context,
|
||||
}
|
||||
}
|
||||
|
||||
func (err *SDKError) Error() string {
|
||||
return fmt.Sprintf("SDKError:\n Code: %s\n Message: %s\n Data: %s\n",
|
||||
StringValue(err.Code), StringValue(err.Message), StringValue(err.Data))
|
||||
}
|
||||
|
||||
func ToObject(obj interface{}) map[string]interface{} {
|
||||
result := make(map[string]interface{})
|
||||
byt, _ := json.Marshal(obj)
|
||||
@@ -759,8 +778,14 @@ func Sleep(backoffTime *int) {
|
||||
}
|
||||
|
||||
func Validate(params interface{}) error {
|
||||
requestValue := reflect.ValueOf(params).Elem()
|
||||
err := validate(requestValue)
|
||||
if params == nil {
|
||||
return nil
|
||||
}
|
||||
requestValue := reflect.ValueOf(params)
|
||||
if requestValue.IsNil() {
|
||||
return nil
|
||||
}
|
||||
err := validate(requestValue.Elem())
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -795,12 +820,12 @@ func validateParam(field reflect.StructField, valueField reflect.Value, tagName
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(field.Type.String(), "[]") { // Verify the parameters of the array type
|
||||
err := validateSlice(valueField, containsTag, tag, tagName)
|
||||
err := validateSlice(field, valueField, containsTag, tag, tagName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if valueField.Kind() == reflect.Ptr { // Determines whether it is a pointer object
|
||||
err := validatePtr(valueField, containsTag, tag, tagName)
|
||||
err := validatePtr(field, valueField, containsTag, tag, tagName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -808,12 +833,28 @@ func validateParam(field reflect.StructField, valueField reflect.Value, tagName
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateSlice(valueField reflect.Value, containsregexpTag bool, tag, tagName string) error {
|
||||
func validateSlice(field reflect.StructField, valueField reflect.Value, containsregexpTag bool, tag, tagName string) error {
|
||||
if valueField.IsValid() && !valueField.IsNil() { // Determines whether the parameter has a value
|
||||
if containsregexpTag {
|
||||
if tagName == "maxItems" {
|
||||
err := checkMaxItems(field, valueField, tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if tagName == "minItems" {
|
||||
err := checkMinItems(field, valueField, tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for m := 0; m < valueField.Len(); m++ {
|
||||
elementValue := valueField.Index(m)
|
||||
if elementValue.Type().Kind() == reflect.Ptr { // Determines whether the child elements of an array are of a basic type
|
||||
err := validatePtr(elementValue, containsregexpTag, tag, tagName)
|
||||
err := validatePtr(field, elementValue, containsregexpTag, tag, tagName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -823,43 +864,42 @@ func validateSlice(valueField reflect.Value, containsregexpTag bool, tag, tagNam
|
||||
return nil
|
||||
}
|
||||
|
||||
func validatePtr(elementValue reflect.Value, containsregexpTag bool, tag, tagName string) error {
|
||||
func validatePtr(field reflect.StructField, elementValue reflect.Value, containsregexpTag bool, tag, tagName string) error {
|
||||
if elementValue.IsNil() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if isFilterType(elementValue.Elem().Type().String(), basicTypes) {
|
||||
if containsregexpTag {
|
||||
if tagName == "pattern" {
|
||||
err := checkPattern(elementValue.Elem(), tag)
|
||||
err := checkPattern(field, elementValue.Elem(), tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if tagName == "maxLength" {
|
||||
err := checkMaxLength(elementValue.Elem(), tag)
|
||||
err := checkMaxLength(field, elementValue.Elem(), tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if tagName == "minLength" {
|
||||
err := checkMinLength(elementValue.Elem(), tag)
|
||||
err := checkMinLength(field, elementValue.Elem(), tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if tagName == "maximum" {
|
||||
err := checkMaximum(elementValue.Elem(), tag)
|
||||
err := checkMaximum(field, elementValue.Elem(), tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if tagName == "minimum" {
|
||||
err := checkMinimum(elementValue.Elem(), tag)
|
||||
err := checkMinimum(field, elementValue.Elem(), tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -884,7 +924,7 @@ func checkRequire(field reflect.StructField, valueField reflect.Value) error {
|
||||
return errors.New(name + " should be setted")
|
||||
}
|
||||
|
||||
func checkPattern(valueField reflect.Value, tag string) error {
|
||||
func checkPattern(field reflect.StructField, valueField reflect.Value, tag string) error {
|
||||
if valueField.IsValid() && valueField.String() != "" {
|
||||
value := valueField.String()
|
||||
if match, _ := regexp.MatchString(tag, value); !match { // Determines whether the parameter value satisfies the regular expression or not, and throws an error
|
||||
@@ -894,7 +934,37 @@ func checkPattern(valueField reflect.Value, tag string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkMaxLength(valueField reflect.Value, tag string) error {
|
||||
func checkMaxItems(field reflect.StructField, valueField reflect.Value, tag string) error {
|
||||
if valueField.IsValid() && valueField.String() != "" {
|
||||
maxItems, err := strconv.Atoi(tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
length := valueField.Len()
|
||||
if maxItems < length {
|
||||
errMsg := fmt.Sprintf("The length of %s is %d which is more than %d", field.Name, length, maxItems)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkMinItems(field reflect.StructField, valueField reflect.Value, tag string) error {
|
||||
if valueField.IsValid() {
|
||||
minItems, err := strconv.Atoi(tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
length := valueField.Len()
|
||||
if minItems > length {
|
||||
errMsg := fmt.Sprintf("The length of %s is %d which is less than %d", field.Name, length, minItems)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkMaxLength(field reflect.StructField, valueField reflect.Value, tag string) error {
|
||||
if valueField.IsValid() && valueField.String() != "" {
|
||||
maxLength, err := strconv.Atoi(tag)
|
||||
if err != nil {
|
||||
@@ -905,14 +975,14 @@ func checkMaxLength(valueField reflect.Value, tag string) error {
|
||||
length = strings.Count(valueField.String(), "") - 1
|
||||
}
|
||||
if maxLength < length {
|
||||
errMsg := fmt.Sprintf("Length of %s is more than %d", valueField.String(), maxLength)
|
||||
errMsg := fmt.Sprintf("The length of %s is %d which is more than %d", field.Name, length, maxLength)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkMinLength(valueField reflect.Value, tag string) error {
|
||||
func checkMinLength(field reflect.StructField, valueField reflect.Value, tag string) error {
|
||||
if valueField.IsValid() {
|
||||
minLength, err := strconv.Atoi(tag)
|
||||
if err != nil {
|
||||
@@ -923,14 +993,14 @@ func checkMinLength(valueField reflect.Value, tag string) error {
|
||||
length = strings.Count(valueField.String(), "") - 1
|
||||
}
|
||||
if minLength > length {
|
||||
errMsg := fmt.Sprintf("Length of %s is less than %d", valueField.String(), minLength)
|
||||
errMsg := fmt.Sprintf("The length of %s is %d which is less than %d", field.Name, length, minLength)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkMaximum(valueField reflect.Value, tag string) error {
|
||||
func checkMaximum(field reflect.StructField, valueField reflect.Value, tag string) error {
|
||||
if valueField.IsValid() && valueField.String() != "" {
|
||||
maximum, err := strconv.ParseFloat(tag, 64)
|
||||
if err != nil {
|
||||
@@ -942,14 +1012,14 @@ func checkMaximum(valueField reflect.Value, tag string) error {
|
||||
return err
|
||||
}
|
||||
if maximum < num {
|
||||
errMsg := fmt.Sprintf("%f is greater than %f", num, maximum)
|
||||
errMsg := fmt.Sprintf("The size of %s is %f which is greater than %f", field.Name, num, maximum)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkMinimum(valueField reflect.Value, tag string) error {
|
||||
func checkMinimum(field reflect.StructField, valueField reflect.Value, tag string) error {
|
||||
if valueField.IsValid() && valueField.String() != "" {
|
||||
minimum, err := strconv.ParseFloat(tag, 64)
|
||||
if err != nil {
|
||||
@@ -962,7 +1032,7 @@ func checkMinimum(valueField reflect.Value, tag string) error {
|
||||
return err
|
||||
}
|
||||
if minimum > num {
|
||||
errMsg := fmt.Sprintf("%f is less than %f", num, minimum)
|
||||
errMsg := fmt.Sprintf("The size of %s is %f which is less than %f", field.Name, num, minimum)
|
||||
return errors.New(errMsg)
|
||||
}
|
||||
}
|
||||
|
||||
+70
-12
@@ -55,7 +55,9 @@ type validateTest struct {
|
||||
MinLength *errMinLength `json:"MinLength,omitempty"`
|
||||
Maximum *errMaximum `json:"Maximum,omitempty"`
|
||||
Minimum *errMinimum `json:"Minimum,omitempty"`
|
||||
List []*string `json:"list,omitempty" pattern:"^[a-d]*$" maxLength:"4"`
|
||||
MaxItems *errMaxItems `json:"MaxItems,omitempty"`
|
||||
MinItems *errMinItems `json:"MinItems,omitempty"`
|
||||
List []*string `json:"list,omitempty" pattern:"^[a-d]*$" minItems:"2" maxItems:"3" maxLength:"4"`
|
||||
}
|
||||
|
||||
type errMaxLength struct {
|
||||
@@ -74,6 +76,14 @@ type errMinimum struct {
|
||||
Num *int `json:"num" minimum:"a"`
|
||||
}
|
||||
|
||||
type errMaxItems struct {
|
||||
NumMax []*int `json:"num" maxItems:"a"`
|
||||
}
|
||||
|
||||
type errMinItems struct {
|
||||
NumMin []*int `json:"num" minItems:"a"`
|
||||
}
|
||||
|
||||
type Progresstest struct {
|
||||
}
|
||||
|
||||
@@ -158,6 +168,9 @@ func TestSDKError(t *testing.T) {
|
||||
})
|
||||
utils.AssertNotNil(t, err)
|
||||
utils.AssertEqual(t, "SDKError:\n Code: code\n Message: message\n Data: {\"hostId\":\"github.com/alibabacloud/tea\",\"httpCode\":\"404\",\"requestId\":\"dfadfa32cgfdcasd4313\"}\n", err.Error())
|
||||
|
||||
err.SetErrMsg("test")
|
||||
utils.AssertEqual(t, "test", err.Error())
|
||||
}
|
||||
|
||||
func TestSDKErrorCode404(t *testing.T) {
|
||||
@@ -370,6 +383,7 @@ func Test_DoRequest(t *testing.T) {
|
||||
|
||||
request.Pathname = String("?log")
|
||||
request.Headers["tea"] = String("")
|
||||
request.Headers["content-length"] = nil
|
||||
runtimeObj["httpsProxy"] = "http://someuser:somepassword@ecs.aliyun.com"
|
||||
resp, err = DoRequest(request, runtimeObj)
|
||||
utils.AssertNil(t, resp)
|
||||
@@ -551,6 +565,27 @@ func Test_Validate(t *testing.T) {
|
||||
}
|
||||
err := Validate(config)
|
||||
utils.AssertNil(t, err)
|
||||
|
||||
err = Validate(new(validateTest))
|
||||
utils.AssertEqual(t, err.Error(), "num1 should be setted")
|
||||
|
||||
var tmp *validateTest
|
||||
err = Validate(tmp)
|
||||
utils.AssertNil(t, err)
|
||||
|
||||
err = Validate(nil)
|
||||
utils.AssertNil(t, err)
|
||||
}
|
||||
|
||||
func Test_Recover(t *testing.T) {
|
||||
err := Recover(nil)
|
||||
utils.AssertNil(t, err)
|
||||
defer func() {
|
||||
if r := Recover(recover()); r != nil {
|
||||
utils.AssertEqual(t, "test", r.Error())
|
||||
}
|
||||
}()
|
||||
panic("test")
|
||||
}
|
||||
|
||||
func Test_validate(t *testing.T) {
|
||||
@@ -564,7 +599,6 @@ func Test_validate(t *testing.T) {
|
||||
Num1: &num,
|
||||
Num2: &num,
|
||||
Str: &str0,
|
||||
List: []*string{&str0},
|
||||
}
|
||||
|
||||
err = validate(reflect.ValueOf(val))
|
||||
@@ -572,7 +606,7 @@ func Test_validate(t *testing.T) {
|
||||
|
||||
val.Str = &str1
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, "Length of abcddd is more than 4", err.Error())
|
||||
utils.AssertEqual(t, "The length of Str is 6 which is more than 4", err.Error())
|
||||
|
||||
val.Num1 = nil
|
||||
err = validate(reflect.ValueOf(val))
|
||||
@@ -584,13 +618,35 @@ func Test_validate(t *testing.T) {
|
||||
|
||||
val.Num1 = &num
|
||||
val.Str = &str0
|
||||
val.List = []*string{&str1}
|
||||
val.List = []*string{&str0}
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, "Length of abcddd is more than 4", err.Error())
|
||||
utils.AssertEqual(t, "The length of List is 1 which is less than 2", err.Error())
|
||||
|
||||
val.Str = nil
|
||||
val.List = []*string{&str0, &str1}
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, "Length of abcddd is more than 4", err.Error())
|
||||
utils.AssertEqual(t, "The length of List is 6 which is more than 4", err.Error())
|
||||
|
||||
val.List = []*string{&str0, &str0}
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertNil(t, err)
|
||||
|
||||
val.MaxItems = &errMaxItems{
|
||||
NumMax: []*int{&num},
|
||||
}
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error())
|
||||
|
||||
val.MaxItems = nil
|
||||
val.MinItems = &errMinItems{
|
||||
NumMin: []*int{&num},
|
||||
}
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error())
|
||||
|
||||
val.MinItems = nil
|
||||
val.List = []*string{&str0, &str0, &str0, &str0}
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, "The length of List is 4 which is more than 3", err.Error())
|
||||
|
||||
str2 := "test"
|
||||
val.Str = &str2
|
||||
@@ -605,6 +661,7 @@ func Test_validate(t *testing.T) {
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error())
|
||||
|
||||
val.List = nil
|
||||
val.MaxLength = nil
|
||||
val.MinLength = &errMinLength{
|
||||
Num: &num,
|
||||
@@ -612,6 +669,7 @@ func Test_validate(t *testing.T) {
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, `strconv.Atoi: parsing "a": invalid syntax`, err.Error())
|
||||
|
||||
val.Name2 = String("tea")
|
||||
val.MinLength = nil
|
||||
val.Maximum = &errMaximum{
|
||||
Num: &num,
|
||||
@@ -629,22 +687,22 @@ func Test_validate(t *testing.T) {
|
||||
val.Minimum = nil
|
||||
val.Num2 = Int(10)
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, `10.000000 is greater than 6.000000`, err.Error())
|
||||
utils.AssertEqual(t, `The size of Num2 is 10.000000 which is greater than 6.000000`, err.Error())
|
||||
|
||||
val.Num2 = nil
|
||||
val.Name1 = String("maxLengthTouch")
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, `Length of maxLengthTouch is more than 4`, err.Error())
|
||||
utils.AssertEqual(t, `The length of Name1 is 14 which is more than 4`, err.Error())
|
||||
|
||||
val.Name1 = nil
|
||||
val.Name2 = String("")
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, `Length of is less than 2`, err.Error())
|
||||
utils.AssertEqual(t, `The length of Name2 is 0 which is less than 2`, err.Error())
|
||||
|
||||
val.Name2 = nil
|
||||
val.Name2 = String("tea")
|
||||
val.Num1 = Int(0)
|
||||
err = validate(reflect.ValueOf(val))
|
||||
utils.AssertEqual(t, `0.000000 is less than 2.000000`, err.Error())
|
||||
utils.AssertEqual(t, `The size of Num1 is 0.000000 which is less than 2.000000`, err.Error())
|
||||
}
|
||||
|
||||
func Test_Prettify(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user