Merge pull request #46994 from thaJeztah/23.0_backport_46621-container_wait
[23.0 backport] Ensure that non-JSON-parsing errors are returned to the caller
This commit is contained in:
commit
d67439d7b6
2 changed files with 49 additions and 2 deletions
|
@ -66,8 +66,12 @@ func (cli *Client) ContainerWait(ctx context.Context, containerID string, condit
|
||||||
//
|
//
|
||||||
// If there's a JSON parsing error, read the real error message
|
// If there's a JSON parsing error, read the real error message
|
||||||
// off the body and send it to the client.
|
// off the body and send it to the client.
|
||||||
_, _ = io.ReadAll(io.LimitReader(stream, containerWaitErrorMsgLimit))
|
if errors.As(err, new(*json.SyntaxError)) {
|
||||||
errC <- errors.New(responseText.String())
|
_, _ = io.ReadAll(io.LimitReader(stream, containerWaitErrorMsgLimit))
|
||||||
|
errC <- errors.New(responseText.String())
|
||||||
|
} else {
|
||||||
|
errC <- err
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,14 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
"testing/iotest"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/errdefs"
|
"github.com/docker/docker/errdefs"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestContainerWaitError(t *testing.T) {
|
func TestContainerWaitError(t *testing.T) {
|
||||||
|
@ -117,6 +120,46 @@ func TestContainerWaitProxyInterruptLong(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContainerWaitErrorHandling(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
name string
|
||||||
|
rdr io.Reader
|
||||||
|
exp error
|
||||||
|
}{
|
||||||
|
{name: "invalid json", rdr: strings.NewReader(`{]`), exp: errors.New("{]")},
|
||||||
|
{name: "context canceled", rdr: iotest.ErrReader(context.Canceled), exp: context.Canceled},
|
||||||
|
{name: "context deadline exceeded", rdr: iotest.ErrReader(context.DeadlineExceeded), exp: context.DeadlineExceeded},
|
||||||
|
{name: "connection reset", rdr: iotest.ErrReader(syscall.ECONNRESET), exp: syscall.ECONNRESET},
|
||||||
|
} {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
version: "1.30",
|
||||||
|
client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
||||||
|
return &http.Response{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Body: io.NopCloser(test.rdr),
|
||||||
|
}, nil
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
resultC, errC := client.ContainerWait(ctx, "container_id", "")
|
||||||
|
select {
|
||||||
|
case err := <-errC:
|
||||||
|
if err.Error() != test.exp.Error() {
|
||||||
|
t.Fatalf("ContainerWait() errC = %v; want %v", err, test.exp)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
case result := <-resultC:
|
||||||
|
t.Fatalf("expected to not get a wait result, got %d", result.StatusCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Unexpected - we should not reach this line
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleClient_ContainerWait_withTimeout() {
|
func ExampleClient_ContainerWait_withTimeout() {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
Loading…
Reference in a new issue