Proper error handling with Sushy emulator
This change adds a more informative error message in case of using airshipctl with a Sushy emulator. In the current implementation, by executing `airshipctl baremetal powerstatus` command with invalid BMH configuration for example, returns: redfish client encountered an error: BMC responded '500 INTERNAL SERVER ERROR'. After this change the output looks like this: redfish client encountered an error: BMC responded '500 INTERNAL SERVER ERROR'. BMC responded: 'Error finding domain by name/UUID "air-ephemeral1" at libvirt URI qemu:///system": Domain not found: no domain with matching name 'air-ephemeral1'' In case of using airshipctl with baremetal BMC, extendedInfo contains a valid error message, so there are no issues. Relates-To: #320 Change-Id: I437f50d5df4b0561f352804f269b0319badcc755
This commit is contained in:
parent
8b891e2d49
commit
068718e07d
@ -33,28 +33,28 @@ const (
|
||||
redfishURLSchemeSeparator = "+"
|
||||
)
|
||||
|
||||
func processExtendedInfo(extendedInfo map[string]interface{}) (string, error) {
|
||||
message, ok := extendedInfo["Message"]
|
||||
if !ok {
|
||||
return "", ErrUnrecognizedRedfishResponse{Key: "error.@Message.ExtendedInfo.Message"}
|
||||
}
|
||||
|
||||
messageContent, ok := message.(string)
|
||||
if !ok {
|
||||
return "", ErrUnrecognizedRedfishResponse{Key: "error.@Message.ExtendedInfo.Message"}
|
||||
}
|
||||
|
||||
// Resolution may be omitted in some responses
|
||||
if resolution, ok := extendedInfo["Resolution"]; ok {
|
||||
return fmt.Sprintf("%s %s", messageContent, resolution), nil
|
||||
}
|
||||
|
||||
return messageContent, nil
|
||||
}
|
||||
|
||||
// DecodeRawError decodes a raw Redfish HTTP response and retrieves the extended information and available resolutions
|
||||
// returned by the BMC.
|
||||
func DecodeRawError(rawResponse []byte) (string, error) {
|
||||
processExtendedInfo := func(extendedInfo map[string]interface{}) (string, error) {
|
||||
message, ok := extendedInfo["Message"]
|
||||
if !ok {
|
||||
return "", ErrUnrecognizedRedfishResponse{Key: "error.@Message.ExtendedInfo.Message"}
|
||||
}
|
||||
|
||||
messageContent, ok := message.(string)
|
||||
if !ok {
|
||||
return "", ErrUnrecognizedRedfishResponse{Key: "error.@Message.ExtendedInfo.Message"}
|
||||
}
|
||||
|
||||
// Resolution may be omitted in some responses
|
||||
if resolution, ok := extendedInfo["Resolution"]; ok {
|
||||
return fmt.Sprintf("%s %s", messageContent, resolution), nil
|
||||
}
|
||||
|
||||
return messageContent, nil
|
||||
}
|
||||
|
||||
// Unmarshal raw Redfish response as arbitrary JSON map
|
||||
var arbitraryJSON map[string]interface{}
|
||||
if err := json.Unmarshal(rawResponse, &arbitraryJSON); err != nil {
|
||||
@ -81,7 +81,7 @@ func DecodeRawError(rawResponse []byte) (string, error) {
|
||||
switch extendedInfo := extendedInfoContent.(type) {
|
||||
case []interface{}:
|
||||
if len(extendedInfo) == 0 {
|
||||
return "", ErrUnrecognizedRedfishResponse{Key: "error.@MessageExtendedInfo"}
|
||||
return "", ErrUnrecognizedRedfishResponse{Key: "error.@Message.ExtendedInfo"}
|
||||
}
|
||||
|
||||
var errorMessage string
|
||||
@ -91,6 +91,10 @@ func DecodeRawError(rawResponse []byte) (string, error) {
|
||||
return "", ErrUnrecognizedRedfishResponse{Key: "error.@Message.ExtendedInfo"}
|
||||
}
|
||||
|
||||
if _, ok := infoContent["Message"]; !ok {
|
||||
return errContent["message"].(string), nil
|
||||
}
|
||||
|
||||
message, err := processExtendedInfo(infoContent)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -208,9 +212,7 @@ func ScreenRedfishError(httpResp *http.Response, clientErr error) error {
|
||||
httpResp.Status),
|
||||
}
|
||||
default:
|
||||
finalError = ErrRedfishClient{Message: fmt.Sprintf("BMC responded '%s'.", httpResp.Status)}
|
||||
log.Debugf("BMC responded '%s'. Attempting to unmarshal the raw BMC error response.",
|
||||
httpResp.Status)
|
||||
finalError = ErrRedfishClient{Message: httpResp.Status}
|
||||
}
|
||||
|
||||
// Retrieve the raw HTTP response body
|
||||
@ -221,7 +223,7 @@ func ScreenRedfishError(httpResp *http.Response, clientErr error) error {
|
||||
|
||||
// Attempt to decode the BMC response from the raw HTTP response
|
||||
if bmcResponse, err := DecodeRawError(oAPIErr.Body()); err == nil {
|
||||
finalError.Message = fmt.Sprintf("%s BMC responded: '%s'", finalError.Message, bmcResponse)
|
||||
finalError.Message = fmt.Sprintf("%s\nBMC responded: '%s'", finalError.Message, bmcResponse)
|
||||
} else {
|
||||
log.Debugf("Unable to decode BMC response. %q", err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user