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.
This commit is contained in:
Quan Tian 2024-07-22 17:13:43 +08:00
parent 00d03ec049
commit 596c5696c6
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,
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(),