Example #1
0
File: client.go Project: bac/juju
// WithOdataErrorUnlessStatusCode returns a RespondDecorator that emits an
// azure.RequestError by reading the response body unless the response HTTP status code
// is among the set passed.
//
// If there is a chance service may return responses other than the Azure error
// format and the response cannot be parsed into an error, a decoding error will
// be returned containing the response body. In any case, the Responder will
// return an error if the status code is not satisfied.
//
// If this Responder returns an error, the response body will be replaced with
// an in-memory reader, which needs no further closing.
//
// NOTE(axw) this function is based on go-autorest/autorest/azure.WithErrorUnlessStatusCode.
// The only difference is that we extract "odata.error", instead of "error",
// from the response body; and we do not extract the message, which is in a
// different format for odata.error, and irrelevant to us.
func WithOdataErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator {
	return func(r autorest.Responder) autorest.Responder {
		return autorest.ResponderFunc(func(resp *http.Response) error {
			err := r.Respond(resp)
			if err == nil && !autorest.ResponseHasStatusCode(resp, codes...) {
				var oe odataRequestError
				defer resp.Body.Close()

				// Copy and replace the Body in case it does not contain an error object.
				// This will leave the Body available to the caller.
				b, decodeErr := autorest.CopyAndDecode(autorest.EncodedAsJSON, resp.Body, &oe)
				resp.Body = ioutil.NopCloser(&b)
				if decodeErr != nil {
					return fmt.Errorf("ad: error response cannot be parsed: %q error: %v", b.String(), decodeErr)
				} else if oe.ServiceError == nil {
					oe.ServiceError = &odataServiceError{Code: "Unknown"}
				}

				e := azure.RequestError{
					ServiceError: &azure.ServiceError{Code: oe.ServiceError.Code},
					RequestID:    azure.ExtractRequestID(resp),
				}
				if e.StatusCode == nil {
					e.StatusCode = resp.StatusCode
				}
				err = &e
			}
			return err
		})
	}
}
Example #2
0
// WithErrorUnlessStatusCode returns a RespondDecorator that emits an
// azure.RequestError by reading the response body unless the response HTTP status code
// is among the set passed.
//
// If there is a chance service may return responses other than the Azure error
// format and the response cannot be parsed into an error, a decoding error will
// be returned containing the response body. In any case, the Responder will
// return an error if the status code is not satisfied.
//
// If this Responder returns an error, the response body will be replaced with
// an in-memory reader, which needs no further closing.
func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator {
	return func(r autorest.Responder) autorest.Responder {
		return autorest.ResponderFunc(func(resp *http.Response) error {
			err := r.Respond(resp)
			if err == nil && !autorest.ResponseHasStatusCode(resp, codes...) {
				var e RequestError
				defer resp.Body.Close()

				b, decodeErr := autorest.CopyAndDecode(autorest.EncodedAsJSON, resp.Body, &e)
				resp.Body = ioutil.NopCloser(&b) // replace body with in-memory reader
				if decodeErr != nil || e.ServiceError == nil {
					return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), err)
				}

				e.RequestID = ExtractRequestID(resp)
				e.StatusCode = resp.StatusCode
				err = &e
			}
			return err
		})
	}
}