Explorar el Código

Merge pull request #41778 from kplachkov/feature/fix_err_canceled

Fix converting status code to error canceled
Akihiro Suda hace 4 años
padre
commit
b9ad7b96bd
Se han modificado 2 ficheros con 50 adiciones y 3 borrados
  1. 8 3
      client/request.go
  2. 42 0
      client/request_test.go

+ 8 - 3
client/request.go

@@ -110,11 +110,16 @@ func (cli *Client) sendRequest(ctx context.Context, method, path string, query u
 	if err != nil {
 		return serverResponse{}, err
 	}
+
 	resp, err := cli.doRequest(ctx, req)
-	if err != nil {
-		return resp, errdefs.FromStatusCode(err, resp.statusCode)
+	switch {
+	case errors.Is(err, context.Canceled):
+		return serverResponse{}, errdefs.Cancelled(err)
+	case errors.Is(err, context.DeadlineExceeded):
+		return serverResponse{}, errdefs.Deadline(err)
+	case err == nil:
+		err = cli.checkResponseErr(resp)
 	}
-	err = cli.checkResponseErr(resp)
 	return resp, errdefs.FromStatusCode(err, resp.statusCode)
 }
 

+ 42 - 0
client/request_test.go

@@ -3,12 +3,14 @@ package client // import "github.com/docker/docker/client"
 import (
 	"bytes"
 	"context"
+	"errors"
 	"fmt"
 	"io/ioutil"
 	"math/rand"
 	"net/http"
 	"strings"
 	"testing"
+	"time"
 
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/errdefs"
@@ -105,3 +107,43 @@ func TestInfiniteError(t *testing.T) {
 	_, err := client.Ping(context.Background())
 	assert.Check(t, is.ErrorContains(err, "request returned Internal Server Error"))
 }
+
+func TestCanceledContext(t *testing.T) {
+	testURL := "/test"
+
+	client := &Client{
+		client: newMockClient(func(req *http.Request) (*http.Response, error) {
+			assert.Equal(t, req.Context().Err(), context.Canceled)
+
+			return &http.Response{}, context.Canceled
+		}),
+	}
+
+	ctx, cancel := context.WithCancel(context.Background())
+	cancel()
+
+	_, err := client.sendRequest(ctx, http.MethodGet, testURL, nil, nil, nil)
+	assert.Equal(t, true, errdefs.IsCancelled(err))
+	assert.Equal(t, true, errors.Is(err, context.Canceled))
+}
+
+func TestDeadlineExceededContext(t *testing.T) {
+	testURL := "/test"
+
+	client := &Client{
+		client: newMockClient(func(req *http.Request) (*http.Response, error) {
+			assert.Equal(t, req.Context().Err(), context.DeadlineExceeded)
+
+			return &http.Response{}, context.DeadlineExceeded
+		}),
+	}
+
+	ctx, cancel := context.WithDeadline(context.Background(), time.Now())
+	defer cancel()
+
+	<-ctx.Done()
+
+	_, err := client.sendRequest(ctx, http.MethodGet, testURL, nil, nil, nil)
+	assert.Equal(t, true, errdefs.IsDeadline(err))
+	assert.Equal(t, true, errors.Is(err, context.DeadlineExceeded))
+}