in whisk/client.go [375:465]
func (c *Client) Do(req *http.Request, v interface{}, ExitWithErrorOnTimeout bool, secretToObfuscate ...ObfuscateSet) (*http.Response, error) {
var err error
var data []byte
secrets := append(DefaultObfuscateArr, secretToObfuscate...)
req, err = PrintRequestInfo(req, secrets...)
//Putting this based on previous code
if err != nil {
return nil, err
}
// Issue the request to the Whisk server endpoint
resp, err := c.client.Do(req)
if err != nil {
Debug(DbgError, "HTTP Do() [req %s] error: %s\n", req.URL.String(), err)
werr := MakeWskError(err, EXIT_CODE_ERR_NETWORK, DISPLAY_MSG, NO_DISPLAY_USAGE)
return nil, werr
}
resp, data, err = PrintResponseInfo(resp, secrets...)
if err != nil {
return resp, err
}
// With the HTTP response status code and the HTTP body contents,
// the possible response scenarios are:
//
// 0. HTTP Success + Body indicating a whisk failure result
// 1. HTTP Success + Valid body matching request expectations
// 2. HTTP Success + No body expected
// 3. HTTP Success + Body does NOT match request expectations
// 4. HTTP Failure + No body
// 5. HTTP Failure + Body matching error format expectation
// 6. HTTP Failure + Body NOT matching error format expectation
// Handle 4. HTTP Failure + No body
// If this happens, just return no data and an error
if !IsHttpRespSuccess(resp) && data == nil {
Debug(DbgError, "HTTP failure %d + no body\n", resp.StatusCode)
werr := MakeWskError(errors.New(wski18n.T("Command failed due to an HTTP failure")), resp.StatusCode-256,
DISPLAY_MSG, NO_DISPLAY_USAGE)
return resp, werr
}
// Handle 5. HTTP Failure + Body matching error format expectation, or body matching a whisk.error() response
// Handle 6. HTTP Failure + Body NOT matching error format expectation
if !IsHttpRespSuccess(resp) && data != nil {
return parseErrorResponse(resp, data, v)
}
// Handle 0. HTTP Success + Body indicating a whisk failure result
// NOTE: Need to ignore activation records send in response to 'wsk get activation NNN` as
// these will report the same original error giving the appearance that the command failed.
// Need to ignore `wsk action invoke NNN --result` too, otherwise action whose result is sth likes
// '{"response": {"key": "value"}}' will return an error to such command.
if IsHttpRespSuccess(resp) && // HTTP Status == 200
data != nil && // HTTP response body exists
v != nil &&
!strings.Contains(reflect.TypeOf(v).String(), "Activation") && // Request is not `wsk activation get`
!(req.URL.Query().Get("result") == "true") && // Request is not `wsk action invoke NNN --result`
!IsResponseResultSuccess(data) { // HTTP response body has Whisk error result
Debug(DbgInfo, "Got successful HTTP; but activation response reports an error\n")
return parseErrorResponse(resp, data, v)
}
// Handle 2. HTTP Success + No body expected
if IsHttpRespSuccess(resp) && v == nil {
Debug(DbgInfo, "No interface provided; no HTTP response body expected\n")
return resp, nil
}
// Handle 1. HTTP Success + Valid body matching request expectations
// Handle 3. HTTP Success + Body does NOT match request expectations
if IsHttpRespSuccess(resp) && v != nil {
// If a timeout occurs, 202 HTTP status code is returned, and the caller wishes to handle such an event, return
// an error corresponding with the timeout
if ExitWithErrorOnTimeout && resp.StatusCode == EXIT_CODE_TIMED_OUT {
errMsg := wski18n.T("Request accepted, but processing not completed yet.")
err = MakeWskError(errors.New(errMsg), EXIT_CODE_TIMED_OUT, NO_DISPLAY_MSG, NO_DISPLAY_USAGE,
NO_MSG_DISPLAYED, NO_DISPLAY_PREFIX, NO_APPLICATION_ERR, TIMED_OUT)
}
return parseSuccessResponse(resp, data, v), err
}
// We should never get here, but just in case return failure to keep the compiler happy
werr := MakeWskError(errors.New(wski18n.T("Command failed due to an internal failure")), EXIT_CODE_ERR_GENERAL,
DISPLAY_MSG, NO_DISPLAY_USAGE)
return resp, werr
}