diff --git a/request/unpacker.go b/request/unpacker.go index 589ec37..7ed8699 100644 --- a/request/unpacker.go +++ b/request/unpacker.go @@ -76,29 +76,40 @@ func (u *Unpacker) parseResponse() error { return fmt.Errorf("API Gateway output format error") } } + } else { + u.httpResponse.Body.Close() + err := fmt.Errorf("Response StatusCode: %d", u.httpResponse.StatusCode) + logger.Error(err.Error()) + return err } return nil } func (u *Unpacker) parseError() error { - + if u.output.IsNil() { + return fmt.Errorf("nil returned") + } retCodeValue := u.output.Elem().FieldByName("RetCode") messageValue := u.output.Elem().FieldByName("Message") - if !retCodeValue.Elem().IsValid() || retCodeValue.Type().String() != "*int" { - return fmt.Errorf("can not get retcode") - } - - if retCodeValue.Elem().Int() != 0 { - if !messageValue.Elem().IsValid() || messageValue.Type().String() != "*string" { - return fmt.Errorf("can not get error message") + if retCodeValue.IsValid() && retCodeValue.Type().String() == "*int" && + retCodeValue.Elem().IsValid() { + if retCodeValue.Elem().Int() == 0 { + return nil } - - return &errors.QingCloudError{ + err := &errors.QingCloudError{ RetCode: int(retCodeValue.Elem().Int()), - Message: messageValue.Elem().String(), } + if messageValue.IsValid() && messageValue.Type().String() == "*string" { + if messageValue.Elem().IsValid() { + err.Message = messageValue.Elem().String() + } else { + err.Message = "null" + } + } + return err } - return nil + + return fmt.Errorf("invalid retCodeValue %v returned", retCodeValue) } diff --git a/request/unpacker_test.go b/request/unpacker_test.go index 96fe17c..4848a9d 100644 --- a/request/unpacker_test.go +++ b/request/unpacker_test.go @@ -149,3 +149,50 @@ func TestUnpacker_UnpackHTTPRequestWithError(t *testing.T) { assert.Equal(t, e.RetCode, 1400) } } + +func TestUnpacker_UnpackHTTPRequestWithWrongType2(t *testing.T) { + type DescribeInstanceTypesOutput struct { + RetCode *int `json:"ret_code" name:"ret_code"` + Message *string `json:"message" name:"message"` + } + + httpResponse := &http.Response{Header: http.Header{}} + httpResponse.StatusCode = 200 + httpResponse.Header.Set("Content-Type", "application/json") + responseString := `{ + "message": null, + "ret_code":1400 + }` + httpResponse.Body = ioutil.NopCloser(bytes.NewReader([]byte(responseString))) + + output := &DescribeInstanceTypesOutput{} + outputValue := reflect.ValueOf(output) + unpacker := Unpacker{} + err := unpacker.UnpackHTTPRequest(&data.Operation{}, httpResponse, &outputValue) + if !assert.NotNil(t, err) { + t.FailNow() + } + println("err", err.Error()) +} + +func TestUnpacker_UnpackHTTPRequestWithWrongHTTPStatus(t *testing.T) { + type DescribeInstanceTypesOutput struct { + RetCode *int `json:"ret_code" name:"ret_code"` + Message *string `json:"message" name:"message"` + } + + httpResponse := &http.Response{Header: http.Header{}} + httpResponse.StatusCode = 500 + httpResponse.Header.Set("Content-Type", "application/json") + responseString := "{}" + httpResponse.Body = ioutil.NopCloser(bytes.NewReader([]byte(responseString))) + + output := &DescribeInstanceTypesOutput{} + outputValue := reflect.ValueOf(output) + unpacker := Unpacker{} + err := unpacker.UnpackHTTPRequest(&data.Operation{}, httpResponse, &outputValue) + if !assert.NotNil(t, err) { + t.FailNow() + } + println("err", err.Error()) +}