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.

Kubernetes-commit: 596c5696c64023808af164284263647d795b0ac2
This commit is contained in:
Quan Tian
2024-07-22 17:13:43 +08:00
committed by Kubernetes Publisher
parent 9db830e3b0
commit 009514ecc1
2 changed files with 16 additions and 29 deletions

View File

@@ -752,8 +752,9 @@ func (r *Request) Watch(ctx context.Context) (watch.Interface, error) {
// the server must have sent us an error in 'err'
return true, nil
}
if result := r.transformResponse(resp, req); result.err != nil {
return true, result.err
result := r.transformResponse(resp, req)
if err := result.Error(); err != nil {
return true, err
}
return true, fmt.Errorf("for request %s, got status: %v", url, resp.StatusCode)
}()

View File

@@ -977,7 +977,7 @@ func TestRequestWatch(t *testing.T) {
Err: true,
},
{
name: "server returns forbidden",
name: "server returns forbidden with json content",
Request: &Request{
c: &RESTClient{
content: defaultContentConfig(),
@@ -986,41 +986,27 @@ func TestRequestWatch(t *testing.T) {
},
serverReturns: []responseErr{
{response: &http.Response{
Header: http.Header{"Content-Type": []string{"application/json"}},
StatusCode: http.StatusForbidden,
Body: io.NopCloser(bytes.NewReader([]byte{})),
Body: io.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), &metav1.Status{
Status: metav1.StatusFailure,
Message: "secrets is forbidden",
Reason: metav1.StatusReasonForbidden,
Code: http.StatusForbidden,
})))),
}, err: nil},
},
attemptsExpected: 1,
Expect: []watch.Event{
{
Type: watch.Error,
Object: &metav1.Status{
Status: "Failure",
Code: 500,
Reason: "InternalError",
Message: `an error on the server ("unable to decode an event from the watch stream: test error") has prevented the request from succeeding`,
Details: &metav1.StatusDetails{
Causes: []metav1.StatusCause{
{
Type: "UnexpectedServerResponse",
Message: "unable to decode an event from the watch stream: test error",
},
{
Type: "ClientWatchDecoding",
Message: "unable to decode an event from the watch stream: test error",
},
},
},
},
},
},
Err: true,
Err: true,
ErrFn: func(err error) bool {
if err.Error() != "secrets is forbidden" {
return false
}
return apierrors.IsForbidden(err)
},
},
{
name: "server returns forbidden",
name: "server returns forbidden without content",
Request: &Request{
c: &RESTClient{
content: defaultContentConfig(),