Merge pull request #6579 from deads2k/deads-fix-stream

make .Stream handle error status codes
pull/6/head
Clayton Coleman 2015-04-08 18:21:06 -04:00
commit 4a31da0808
2 changed files with 42 additions and 0 deletions

View File

@ -540,6 +540,8 @@ func isProbableEOF(err error) bool {
// Stream formats and executes the request, and offers streaming of the response.
// Returns io.ReadCloser which could be used for streaming of the response, or an error
// Any non-2xx http status code causes an error. If we get a non-2xx code, we try to convert the body into an APIStatus object.
// If we can, we return that as an error. Otherwise, we create an error that lists the http status and the content of the response.
func (r *Request) Stream() (io.ReadCloser, error) {
if r.err != nil {
return nil, r.err
@ -556,6 +558,30 @@ func (r *Request) Stream() (io.ReadCloser, error) {
if err != nil {
return nil, err
}
switch {
case (resp.StatusCode >= 200) && (resp.StatusCode < 300):
return resp.Body, nil
default:
// we have a decent shot at taking the object returned, parsing it as a status object and returning a more normal error
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("%v while accessing %v", resp.Status, r.finalURL())
}
if runtimeObject, err := r.codec.Decode(bodyBytes); err == nil {
statusError := errors.FromObject(runtimeObject)
if _, ok := statusError.(APIStatus); ok {
return nil, statusError
}
}
bodyText := string(bodyBytes)
return nil, fmt.Errorf("%s while accessing %v: %s", resp.Status, r.finalURL(), bodyText)
}
return resp.Body, nil
}

View File

@ -531,6 +531,22 @@ func TestRequestStream(t *testing.T) {
},
Err: true,
},
{
Request: &Request{
client: clientFunc(func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusUnauthorized,
Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Codec(), &api.Status{
Status: api.StatusFailure,
Reason: api.StatusReasonUnauthorized,
})))),
}, nil
}),
codec: latest.Codec,
baseURL: &url.URL{},
},
Err: true,
},
}
for i, testCase := range testCases {
body, err := testCase.Request.Stream()