Skip to content

Commit 596c569

Browse files
committed
Enrich the error returned from Request.Watch method
The Error method of the error returned from Request.Watch was "unknown" even the server returned clear message in the Status struct. It was because Request.Watch used the Result's err member directly, which is an unstructured error from the response which the Result object may use if the caller did not return a structured error. The patch fixes it by calling the Result's Error method instead, which returns the structured error when it's present. It also removes the wrong expectation about events.
1 parent 00d03ec commit 596c569

File tree

2 files changed

+16
-29
lines changed

2 files changed

+16
-29
lines changed

staging/src/k8s.io/client-go/rest/request.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,8 +752,9 @@ func (r *Request) Watch(ctx context.Context) (watch.Interface, error) {
752752
// the server must have sent us an error in 'err'
753753
return true, nil
754754
}
755-
if result := r.transformResponse(resp, req); result.err != nil {
756-
return true, result.err
755+
result := r.transformResponse(resp, req)
756+
if err := result.Error(); err != nil {
757+
return true, err
757758
}
758759
return true, fmt.Errorf("for request %s, got status: %v", url, resp.StatusCode)
759760
}()

staging/src/k8s.io/client-go/rest/request_test.go

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ func TestRequestWatch(t *testing.T) {
977977
Err: true,
978978
},
979979
{
980-
name: "server returns forbidden",
980+
name: "server returns forbidden with json content",
981981
Request: &Request{
982982
c: &RESTClient{
983983
content: defaultContentConfig(),
@@ -986,41 +986,27 @@ func TestRequestWatch(t *testing.T) {
986986
},
987987
serverReturns: []responseErr{
988988
{response: &http.Response{
989+
Header: http.Header{"Content-Type": []string{"application/json"}},
989990
StatusCode: http.StatusForbidden,
990-
Body: io.NopCloser(bytes.NewReader([]byte{})),
991+
Body: io.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &metav1.Status{
992+
Status: metav1.StatusFailure,
993+
Message: "secrets is forbidden",
994+
Reason: metav1.StatusReasonForbidden,
995+
Code: http.StatusForbidden,
996+
})))),
991997
}, err: nil},
992998
},
993999
attemptsExpected: 1,
994-
Expect: []watch.Event{
995-
{
996-
Type: watch.Error,
997-
Object: &metav1.Status{
998-
Status: "Failure",
999-
Code: 500,
1000-
Reason: "InternalError",
1001-
Message: `an error on the server ("unable to decode an event from the watch stream: test error") has prevented the request from succeeding`,
1002-
Details: &metav1.StatusDetails{
1003-
Causes: []metav1.StatusCause{
1004-
{
1005-
Type: "UnexpectedServerResponse",
1006-
Message: "unable to decode an event from the watch stream: test error",
1007-
},
1008-
{
1009-
Type: "ClientWatchDecoding",
1010-
Message: "unable to decode an event from the watch stream: test error",
1011-
},
1012-
},
1013-
},
1014-
},
1015-
},
1016-
},
1017-
Err: true,
1000+
Err: true,
10181001
ErrFn: func(err error) bool {
1002+
if err.Error() != "secrets is forbidden" {
1003+
return false
1004+
}
10191005
return apierrors.IsForbidden(err)
10201006
},
10211007
},
10221008
{
1023-
name: "server returns forbidden",
1009+
name: "server returns forbidden without content",
10241010
Request: &Request{
10251011
c: &RESTClient{
10261012
content: defaultContentConfig(),

0 commit comments

Comments
 (0)