Skip to content

Commit 067012f

Browse files
authored
client-go: transform watchErrorStream to wrap the underlying error (kubernetes#129765)
* `client-go`: transform `watchErrorStream` to wrap the underlying error This PR transforms the `client-go`'s `watchErrorStream` to wrap the error instead of transforming it into a single string. This enables clients to use `errors.Is/As/Unwrap` with the errors that come out of `StreamWithContext` Fixes kubernetes#129763 * adjust unit tests
1 parent 29bf17b commit 067012f

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

staging/src/k8s.io/client-go/tools/remotecommand/errorstream.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func watchErrorStream(errorStream io.Reader, d errorStreamDecoder) chan error {
4141
message, err := io.ReadAll(errorStream)
4242
switch {
4343
case err != nil && err != io.EOF:
44-
errorChan <- fmt.Errorf("error reading from error stream: %s", err)
44+
errorChan <- fmt.Errorf("error reading from error stream: %w", err)
4545
case len(message) > 0:
4646
errorChan <- d.decode(message)
4747
default:

staging/src/k8s.io/client-go/tools/remotecommand/v2_test.go

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ package remotecommand
1919
import (
2020
"errors"
2121
"io"
22+
"net"
2223
"net/http"
2324
"strings"
2425
"testing"
2526
"time"
2627

27-
"k8s.io/api/core/v1"
28+
v1 "k8s.io/api/core/v1"
2829
"k8s.io/apimachinery/pkg/util/httpstream"
2930
"k8s.io/apimachinery/pkg/util/wait"
3031
)
@@ -181,17 +182,34 @@ func TestV2ErrorStreamReading(t *testing.T) {
181182
tests := []struct {
182183
name string
183184
stream io.Reader
184-
expectedError error
185+
expectedError func(*testing.T, error)
185186
}{
186187
{
187-
name: "error reading from stream",
188-
stream: &fakeReader{errors.New("foo")},
189-
expectedError: errors.New("error reading from error stream: foo"),
188+
name: "error reading from stream",
189+
stream: &fakeReader{errors.New("foo")},
190+
expectedError: func(t *testing.T, err error) {
191+
if e, a := "error reading from error stream: foo", err.Error(); e != a {
192+
t.Errorf("expected '%s', got '%s'", e, a)
193+
}
194+
},
190195
},
191196
{
192-
name: "stream returns an error",
193-
stream: strings.NewReader("some error"),
194-
expectedError: errors.New("error executing remote command: some error"),
197+
name: "stream returns an error",
198+
stream: strings.NewReader("some error"),
199+
expectedError: func(t *testing.T, err error) {
200+
if e, a := "error executing remote command: some error", err.Error(); e != a {
201+
t.Errorf("expected '%s', got '%s'", e, a)
202+
}
203+
},
204+
},
205+
{
206+
name: "typed error",
207+
stream: &fakeReader{net.ErrClosed},
208+
expectedError: func(t *testing.T, err error) {
209+
if !errors.Is(err, net.ErrClosed) {
210+
t.Errorf("expected errors.Is(err, net.ErrClosed), failed on %#v", err)
211+
}
212+
},
195213
},
196214
}
197215

@@ -214,8 +232,8 @@ func TestV2ErrorStreamReading(t *testing.T) {
214232
if test.expectedError != nil {
215233
if err == nil {
216234
t.Errorf("%s: expected an error", test.name)
217-
} else if e, a := test.expectedError, err; e.Error() != a.Error() {
218-
t.Errorf("%s: expected %q, got %q", test.name, e, a)
235+
} else {
236+
test.expectedError(t, err)
219237
}
220238
continue
221239
}

0 commit comments

Comments
 (0)