Ensure that non-JSON-parsing errors are returned to the caller
Signed-off-by: Stefan Gehrig <stefan.gehrig.hn@googlemail.com>
Co-authored-by: Cory Snider <corhere@gmail.com>
(cherry picked from commit 0d27579fc7
)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
4d14c7db67
commit
083ef6617b
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
|
||||
// off the body and send it to the client.
|
||||
_, _ = io.ReadAll(io.LimitReader(stream, containerWaitErrorMsgLimit))
|
||||
errC <- errors.New(responseText.String())
|
||||
if errors.As(err, new(*json.SyntaxError)) {
|
||||
_, _ = io.ReadAll(io.LimitReader(stream, containerWaitErrorMsgLimit))
|
||||
errC <- errors.New(responseText.String())
|
||||
} else {
|
||||
errC <- err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,14 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
"testing/iotest"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
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() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
|
Loading…
Reference in a new issue