decoder_util.go (2268B)
1 package restjson 2 3 import ( 4 "encoding/json" 5 "io" 6 "strings" 7 8 "github.com/aws/smithy-go" 9 ) 10 11 // GetErrorInfo util looks for code, __type, and message members in the 12 // json body. These members are optionally available, and the function 13 // returns the value of member if it is available. This function is useful to 14 // identify the error code, msg in a REST JSON error response. 15 func GetErrorInfo(decoder *json.Decoder) (errorType string, message string, err error) { 16 var errInfo struct { 17 Code string 18 Type string `json:"__type"` 19 Message string 20 } 21 22 err = decoder.Decode(&errInfo) 23 if err != nil { 24 if err == io.EOF { 25 return errorType, message, nil 26 } 27 return errorType, message, err 28 } 29 30 // assign error type 31 if len(errInfo.Code) != 0 { 32 errorType = errInfo.Code 33 } else if len(errInfo.Type) != 0 { 34 errorType = errInfo.Type 35 } 36 37 // assign error message 38 if len(errInfo.Message) != 0 { 39 message = errInfo.Message 40 } 41 42 // sanitize error 43 if len(errorType) != 0 { 44 errorType = SanitizeErrorCode(errorType) 45 } 46 47 return errorType, message, nil 48 } 49 50 // SanitizeErrorCode sanitizes the errorCode string . 51 // The rule for sanitizing is if a `:` character is present, then take only the 52 // contents before the first : character in the value. 53 // If a # character is present, then take only the contents after the 54 // first # character in the value. 55 func SanitizeErrorCode(errorCode string) string { 56 if strings.ContainsAny(errorCode, ":") { 57 errorCode = strings.SplitN(errorCode, ":", 2)[0] 58 } 59 60 if strings.ContainsAny(errorCode, "#") { 61 errorCode = strings.SplitN(errorCode, "#", 2)[1] 62 } 63 64 return errorCode 65 } 66 67 // GetSmithyGenericAPIError returns smithy generic api error and an error interface. 68 // Takes in json decoder, and error Code string as args. The function retrieves error message 69 // and error code from the decoder body. If errorCode of length greater than 0 is passed in as 70 // an argument, it is used instead. 71 func GetSmithyGenericAPIError(decoder *json.Decoder, errorCode string) (*smithy.GenericAPIError, error) { 72 errorType, message, err := GetErrorInfo(decoder) 73 if err != nil { 74 return nil, err 75 } 76 77 if len(errorCode) == 0 { 78 errorCode = errorType 79 } 80 81 return &smithy.GenericAPIError{ 82 Code: errorCode, 83 Message: message, 84 }, nil 85 }