1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #34784 from dnephin/fix-client-not-found

Cleanup client not found errors
This commit is contained in:
Vincent Demeester 2017-09-14 12:04:56 +02:00 committed by GitHub
commit bb0e8ee51c
31 changed files with 86 additions and 263 deletions

View file

@ -2,7 +2,6 @@ package client
import ( import (
"encoding/json" "encoding/json"
"net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -20,10 +19,7 @@ func (cli *Client) CheckpointList(ctx context.Context, container string, options
resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil) resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil)
if err != nil { if err != nil {
if resp.statusCode == http.StatusNotFound { return checkpoints, wrapResponseError(err, resp, "container", container)
return checkpoints, containerNotFoundError{container}
}
return checkpoints, err
} }
err = json.NewDecoder(resp.body).Decode(&checkpoints) err = json.NewDecoder(resp.body).Decode(&checkpoints)

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -17,10 +16,7 @@ func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.C
} }
resp, err := cli.get(ctx, "/configs/"+id, nil, nil) resp, err := cli.get(ctx, "/configs/"+id, nil, nil)
if err != nil { if err != nil {
if resp.statusCode == http.StatusNotFound { return swarm.Config{}, nil, wrapResponseError(err, resp, "config", id)
return swarm.Config{}, nil, configNotFoundError{id}
}
return swarm.Config{}, nil, err
} }
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View file

@ -9,5 +9,5 @@ func (cli *Client) ConfigRemove(ctx context.Context, id string) error {
} }
resp, err := cli.delete(ctx, "/configs/"+id, nil, nil) resp, err := cli.delete(ctx, "/configs/"+id, nil, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return wrapResponseError(err, resp, "config", id)
} }

View file

@ -45,7 +45,7 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config
serverResp, err := cli.post(ctx, "/containers/create", query, body, nil) serverResp, err := cli.post(ctx, "/containers/create", query, body, nil)
if err != nil { if err != nil {
if serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") { if serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") {
return response, imageNotFoundError{config.Image} return response, objectNotFoundError{object: "image", id: config.Image}
} }
return response, err return response, err
} }

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -15,10 +14,7 @@ import (
func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) { func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) {
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil) serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil)
if err != nil { if err != nil {
if serverResp.statusCode == http.StatusNotFound { return types.ContainerJSON{}, wrapResponseError(err, serverResp, "container", containerID)
return types.ContainerJSON{}, containerNotFoundError{containerID}
}
return types.ContainerJSON{}, err
} }
var response types.ContainerJSON var response types.ContainerJSON
@ -35,10 +31,7 @@ func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID stri
} }
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil) serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil)
if err != nil { if err != nil {
if serverResp.statusCode == http.StatusNotFound { return types.ContainerJSON{}, nil, wrapResponseError(err, serverResp, "container", containerID)
return types.ContainerJSON{}, nil, containerNotFoundError{containerID}
}
return types.ContainerJSON{}, nil, err
} }
defer ensureReaderClosed(serverResp) defer ensureReaderClosed(serverResp)

View file

@ -23,5 +23,5 @@ func (cli *Client) ContainerRemove(ctx context.Context, containerID string, opti
resp, err := cli.delete(ctx, "/containers/"+containerID, query, nil) resp, err := cli.delete(ctx, "/containers/"+containerID, query, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return wrapResponseError(err, resp, "container", containerID)
} }

View file

@ -9,6 +9,7 @@ import (
"testing" "testing"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@ -17,9 +18,16 @@ func TestContainerRemoveError(t *testing.T) {
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")),
} }
err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{}) err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" { assert.EqualError(t, err, "Error response from daemon: Server error")
t.Fatalf("expected a Server Error, got %v", err) }
func TestContainerRemoveNotFoundError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusNotFound, "missing")),
} }
err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{})
assert.EqualError(t, err, "Error: No such container: container_id")
assert.True(t, IsErrNotFound(err))
} }
func TestContainerRemove(t *testing.T) { func TestContainerRemove(t *testing.T) {
@ -53,7 +61,5 @@ func TestContainerRemove(t *testing.T) {
RemoveVolumes: true, RemoveVolumes: true,
Force: true, Force: true,
}) })
if err != nil { assert.NoError(t, err)
t.Fatal(err)
}
} }

View file

@ -3,6 +3,8 @@ package client
import ( import (
"fmt" "fmt"
"net/http"
"github.com/docker/docker/api/types/versions" "github.com/docker/docker/api/types/versions"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -43,19 +45,28 @@ func IsErrNotFound(err error) bool {
return ok && te.NotFound() return ok && te.NotFound()
} }
// imageNotFoundError implements an error returned when an image is not in the docker host. type objectNotFoundError struct {
type imageNotFoundError struct { object string
imageID string id string
} }
// NotFound indicates that this error type is of NotFound func (e objectNotFoundError) NotFound() bool {
func (e imageNotFoundError) NotFound() bool {
return true return true
} }
// Error returns a string representation of an imageNotFoundError func (e objectNotFoundError) Error() string {
func (e imageNotFoundError) Error() string { return fmt.Sprintf("Error: No such %s: %s", e.object, e.id)
return fmt.Sprintf("Error: No such image: %s", e.imageID) }
func wrapResponseError(err error, resp serverResponse, object, id string) error {
switch {
case err == nil:
return nil
case resp.statusCode == http.StatusNotFound:
return objectNotFoundError{object: object, id: id}
default:
return err
}
} }
// IsErrImageNotFound returns true if the error is caused // IsErrImageNotFound returns true if the error is caused
@ -66,21 +77,6 @@ func IsErrImageNotFound(err error) bool {
return IsErrNotFound(err) return IsErrNotFound(err)
} }
// containerNotFoundError implements an error returned when a container is not in the docker host.
type containerNotFoundError struct {
containerID string
}
// NotFound indicates that this error type is of NotFound
func (e containerNotFoundError) NotFound() bool {
return true
}
// Error returns a string representation of a containerNotFoundError
func (e containerNotFoundError) Error() string {
return fmt.Sprintf("Error: No such container: %s", e.containerID)
}
// IsErrContainerNotFound returns true if the error is caused // IsErrContainerNotFound returns true if the error is caused
// when a container is not found in the docker host. // when a container is not found in the docker host.
// //
@ -89,21 +85,6 @@ func IsErrContainerNotFound(err error) bool {
return IsErrNotFound(err) return IsErrNotFound(err)
} }
// networkNotFoundError implements an error returned when a network is not in the docker host.
type networkNotFoundError struct {
networkID string
}
// NotFound indicates that this error type is of NotFound
func (e networkNotFoundError) NotFound() bool {
return true
}
// Error returns a string representation of a networkNotFoundError
func (e networkNotFoundError) Error() string {
return fmt.Sprintf("Error: No such network: %s", e.networkID)
}
// IsErrNetworkNotFound returns true if the error is caused // IsErrNetworkNotFound returns true if the error is caused
// when a network is not found in the docker host. // when a network is not found in the docker host.
// //
@ -112,21 +93,6 @@ func IsErrNetworkNotFound(err error) bool {
return IsErrNotFound(err) return IsErrNotFound(err)
} }
// volumeNotFoundError implements an error returned when a volume is not in the docker host.
type volumeNotFoundError struct {
volumeID string
}
// NotFound indicates that this error type is of NotFound
func (e volumeNotFoundError) NotFound() bool {
return true
}
// Error returns a string representation of a volumeNotFoundError
func (e volumeNotFoundError) Error() string {
return fmt.Sprintf("Error: No such volume: %s", e.volumeID)
}
// IsErrVolumeNotFound returns true if the error is caused // IsErrVolumeNotFound returns true if the error is caused
// when a volume is not found in the docker host. // when a volume is not found in the docker host.
// //
@ -152,43 +118,12 @@ func IsErrUnauthorized(err error) bool {
return ok return ok
} }
// nodeNotFoundError implements an error returned when a node is not found.
type nodeNotFoundError struct {
nodeID string
}
// Error returns a string representation of a nodeNotFoundError
func (e nodeNotFoundError) Error() string {
return fmt.Sprintf("Error: No such node: %s", e.nodeID)
}
// NotFound indicates that this error type is of NotFound
func (e nodeNotFoundError) NotFound() bool {
return true
}
// IsErrNodeNotFound returns true if the error is caused // IsErrNodeNotFound returns true if the error is caused
// when a node is not found. // when a node is not found.
// //
// Deprecated: Use IsErrNotFound // Deprecated: Use IsErrNotFound
func IsErrNodeNotFound(err error) bool { func IsErrNodeNotFound(err error) bool {
_, ok := err.(nodeNotFoundError) return IsErrNotFound(err)
return ok
}
// serviceNotFoundError implements an error returned when a service is not found.
type serviceNotFoundError struct {
serviceID string
}
// Error returns a string representation of a serviceNotFoundError
func (e serviceNotFoundError) Error() string {
return fmt.Sprintf("Error: No such service: %s", e.serviceID)
}
// NotFound indicates that this error type is of NotFound
func (e serviceNotFoundError) NotFound() bool {
return true
} }
// IsErrServiceNotFound returns true if the error is caused // IsErrServiceNotFound returns true if the error is caused
@ -196,23 +131,7 @@ func (e serviceNotFoundError) NotFound() bool {
// //
// Deprecated: Use IsErrNotFound // Deprecated: Use IsErrNotFound
func IsErrServiceNotFound(err error) bool { func IsErrServiceNotFound(err error) bool {
_, ok := err.(serviceNotFoundError) return IsErrNotFound(err)
return ok
}
// taskNotFoundError implements an error returned when a task is not found.
type taskNotFoundError struct {
taskID string
}
// Error returns a string representation of a taskNotFoundError
func (e taskNotFoundError) Error() string {
return fmt.Sprintf("Error: No such task: %s", e.taskID)
}
// NotFound indicates that this error type is of NotFound
func (e taskNotFoundError) NotFound() bool {
return true
} }
// IsErrTaskNotFound returns true if the error is caused // IsErrTaskNotFound returns true if the error is caused
@ -220,8 +139,7 @@ func (e taskNotFoundError) NotFound() bool {
// //
// Deprecated: Use IsErrNotFound // Deprecated: Use IsErrNotFound
func IsErrTaskNotFound(err error) bool { func IsErrTaskNotFound(err error) bool {
_, ok := err.(taskNotFoundError) return IsErrNotFound(err)
return ok
} }
type pluginPermissionDenied struct { type pluginPermissionDenied struct {
@ -248,43 +166,12 @@ func (cli *Client) NewVersionError(APIrequired, feature string) error {
return nil return nil
} }
// secretNotFoundError implements an error returned when a secret is not found.
type secretNotFoundError struct {
name string
}
// Error returns a string representation of a secretNotFoundError
func (e secretNotFoundError) Error() string {
return fmt.Sprintf("Error: no such secret: %s", e.name)
}
// NotFound indicates that this error type is of NotFound
func (e secretNotFoundError) NotFound() bool {
return true
}
// IsErrSecretNotFound returns true if the error is caused // IsErrSecretNotFound returns true if the error is caused
// when a secret is not found. // when a secret is not found.
// //
// Deprecated: Use IsErrNotFound // Deprecated: Use IsErrNotFound
func IsErrSecretNotFound(err error) bool { func IsErrSecretNotFound(err error) bool {
_, ok := err.(secretNotFoundError) return IsErrNotFound(err)
return ok
}
// configNotFoundError implements an error returned when a config is not found.
type configNotFoundError struct {
name string
}
// Error returns a string representation of a configNotFoundError
func (e configNotFoundError) Error() string {
return fmt.Sprintf("Error: no such config: %s", e.name)
}
// NotFound indicates that this error type is of NotFound
func (e configNotFoundError) NotFound() bool {
return true
} }
// IsErrConfigNotFound returns true if the error is caused // IsErrConfigNotFound returns true if the error is caused
@ -292,23 +179,7 @@ func (e configNotFoundError) NotFound() bool {
// //
// Deprecated: Use IsErrNotFound // Deprecated: Use IsErrNotFound
func IsErrConfigNotFound(err error) bool { func IsErrConfigNotFound(err error) bool {
_, ok := err.(configNotFoundError) return IsErrNotFound(err)
return ok
}
// pluginNotFoundError implements an error returned when a plugin is not in the docker host.
type pluginNotFoundError struct {
name string
}
// NotFound indicates that this error type is of NotFound
func (e pluginNotFoundError) NotFound() bool {
return true
}
// Error returns a string representation of a pluginNotFoundError
func (e pluginNotFoundError) Error() string {
return fmt.Sprintf("Error: No such plugin: %s", e.name)
} }
// IsErrPluginNotFound returns true if the error is caused // IsErrPluginNotFound returns true if the error is caused

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -14,10 +13,7 @@ import (
func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) { func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) {
serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", nil, nil) serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", nil, nil)
if err != nil { if err != nil {
if serverResp.statusCode == http.StatusNotFound { return types.ImageInspect{}, nil, wrapResponseError(err, serverResp, "image", imageID)
return types.ImageInspect{}, nil, imageNotFoundError{imageID}
}
return types.ImageInspect{}, nil, err
} }
defer ensureReaderClosed(serverResp) defer ensureReaderClosed(serverResp)

View file

@ -2,7 +2,6 @@ package client
import ( import (
"encoding/json" "encoding/json"
"net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -20,15 +19,12 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options type
query.Set("noprune", "1") query.Set("noprune", "1")
} }
var dels []types.ImageDeleteResponseItem
resp, err := cli.delete(ctx, "/images/"+imageID, query, nil) resp, err := cli.delete(ctx, "/images/"+imageID, query, nil)
if err != nil { if err != nil {
if resp.statusCode == http.StatusNotFound { return dels, wrapResponseError(err, resp, "image", imageID)
return nil, imageNotFoundError{imageID}
}
return nil, err
} }
var dels []types.ImageDeleteResponseItem
err = json.NewDecoder(resp.body).Decode(&dels) err = json.NewDecoder(resp.body).Decode(&dels)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return dels, err return dels, err

View file

@ -10,6 +10,7 @@ import (
"testing" "testing"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@ -19,20 +20,17 @@ func TestImageRemoveError(t *testing.T) {
} }
_, err := client.ImageRemove(context.Background(), "image_id", types.ImageRemoveOptions{}) _, err := client.ImageRemove(context.Background(), "image_id", types.ImageRemoveOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" { assert.EqualError(t, err, "Error response from daemon: Server error")
t.Fatalf("expected a Server Error, got %v", err)
}
} }
func TestImageRemoveImageNotFound(t *testing.T) { func TestImageRemoveImageNotFound(t *testing.T) {
client := &Client{ client := &Client{
client: newMockClient(errorMock(http.StatusNotFound, "Server error")), client: newMockClient(errorMock(http.StatusNotFound, "missing")),
} }
_, err := client.ImageRemove(context.Background(), "unknown", types.ImageRemoveOptions{}) _, err := client.ImageRemove(context.Background(), "unknown", types.ImageRemoveOptions{})
if err == nil || !IsErrNotFound(err) { assert.EqualError(t, err, "Error: No such image: unknown")
t.Fatalf("expected an imageNotFoundError error, got %v", err) assert.True(t, IsErrNotFound(err))
}
} }
func TestImageRemove(t *testing.T) { func TestImageRemove(t *testing.T) {

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -33,10 +32,7 @@ func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string,
} }
resp, err = cli.get(ctx, "/networks/"+networkID, query, nil) resp, err = cli.get(ctx, "/networks/"+networkID, query, nil)
if err != nil { if err != nil {
if resp.statusCode == http.StatusNotFound { return networkResource, nil, wrapResponseError(err, resp, "network", networkID)
return networkResource, nil, networkNotFoundError{networkID}
}
return networkResource, nil, err
} }
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View file

@ -21,20 +21,17 @@ func TestNetworkInspectError(t *testing.T) {
} }
_, err := client.NetworkInspect(context.Background(), "nothing", types.NetworkInspectOptions{}) _, err := client.NetworkInspect(context.Background(), "nothing", types.NetworkInspectOptions{})
if err == nil || err.Error() != "Error response from daemon: Server error" { assert.EqualError(t, err, "Error response from daemon: Server error")
t.Fatalf("expected a Server Error, got %v", err)
}
} }
func TestNetworkInspectContainerNotFound(t *testing.T) { func TestNetworkInspectNotFoundError(t *testing.T) {
client := &Client{ client := &Client{
client: newMockClient(errorMock(http.StatusNotFound, "Server error")), client: newMockClient(errorMock(http.StatusNotFound, "missing")),
} }
_, err := client.NetworkInspect(context.Background(), "unknown", types.NetworkInspectOptions{}) _, err := client.NetworkInspect(context.Background(), "unknown", types.NetworkInspectOptions{})
if err == nil || !IsErrNetworkNotFound(err) { assert.EqualError(t, err, "Error: No such network: unknown")
t.Fatalf("expected a networkNotFound error, got %v", err) assert.True(t, IsErrNotFound(err))
}
} }
func TestNetworkInspect(t *testing.T) { func TestNetworkInspect(t *testing.T) {

View file

@ -6,5 +6,5 @@ import "golang.org/x/net/context"
func (cli *Client) NetworkRemove(ctx context.Context, networkID string) error { func (cli *Client) NetworkRemove(ctx context.Context, networkID string) error {
resp, err := cli.delete(ctx, "/networks/"+networkID, nil, nil) resp, err := cli.delete(ctx, "/networks/"+networkID, nil, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return wrapResponseError(err, resp, "network", networkID)
} }

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -14,10 +13,7 @@ import (
func (cli *Client) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) { func (cli *Client) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) {
serverResp, err := cli.get(ctx, "/nodes/"+nodeID, nil, nil) serverResp, err := cli.get(ctx, "/nodes/"+nodeID, nil, nil)
if err != nil { if err != nil {
if serverResp.statusCode == http.StatusNotFound { return swarm.Node{}, nil, wrapResponseError(err, serverResp, "node", nodeID)
return swarm.Node{}, nil, nodeNotFoundError{nodeID}
}
return swarm.Node{}, nil, err
} }
defer ensureReaderClosed(serverResp) defer ensureReaderClosed(serverResp)

View file

@ -17,5 +17,5 @@ func (cli *Client) NodeRemove(ctx context.Context, nodeID string, options types.
resp, err := cli.delete(ctx, "/nodes/"+nodeID, query, nil) resp, err := cli.delete(ctx, "/nodes/"+nodeID, query, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return wrapResponseError(err, resp, "node", nodeID)
} }

View file

@ -28,7 +28,5 @@ func (cli *Client) Ping(ctx context.Context) (types.Ping, error) {
} }
ping.OSType = serverResp.header.Get("OSType") ping.OSType = serverResp.header.Get("OSType")
} }
return ping, cli.checkResponseErr(serverResp)
err = cli.checkResponseErr(serverResp)
return ping, err
} }

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -14,10 +13,7 @@ import (
func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) { func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) {
resp, err := cli.get(ctx, "/plugins/"+name+"/json", nil, nil) resp, err := cli.get(ctx, "/plugins/"+name+"/json", nil, nil)
if err != nil { if err != nil {
if resp.statusCode == http.StatusNotFound { return nil, nil, wrapResponseError(err, resp, "plugin", name)
return nil, nil, pluginNotFoundError{name}
}
return nil, nil, err
} }
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View file

@ -16,5 +16,5 @@ func (cli *Client) PluginRemove(ctx context.Context, name string, options types.
resp, err := cli.delete(ctx, "/plugins/"+name, query, nil) resp, err := cli.delete(ctx, "/plugins/"+name, query, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return wrapResponseError(err, resp, "plugin", name)
} }

View file

@ -203,7 +203,7 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error {
return err return err
} }
if len(body) == 0 { if len(body) == 0 {
return fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), serverResp.reqURL) return fmt.Errorf("request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(serverResp.statusCode), serverResp.reqURL)
} }
var ct string var ct string

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -17,10 +16,7 @@ func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.S
} }
resp, err := cli.get(ctx, "/secrets/"+id, nil, nil) resp, err := cli.get(ctx, "/secrets/"+id, nil, nil)
if err != nil { if err != nil {
if resp.statusCode == http.StatusNotFound { return swarm.Secret{}, nil, wrapResponseError(err, resp, "secret", id)
return swarm.Secret{}, nil, secretNotFoundError{id}
}
return swarm.Secret{}, nil, err
} }
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View file

@ -9,5 +9,5 @@ func (cli *Client) SecretRemove(ctx context.Context, id string) error {
} }
resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil) resp, err := cli.delete(ctx, "/secrets/"+id, nil, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return wrapResponseError(err, resp, "secret", id)
} }

View file

@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http"
"net/url" "net/url"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -19,10 +18,7 @@ func (cli *Client) ServiceInspectWithRaw(ctx context.Context, serviceID string,
query.Set("insertDefaults", fmt.Sprintf("%v", opts.InsertDefaults)) query.Set("insertDefaults", fmt.Sprintf("%v", opts.InsertDefaults))
serverResp, err := cli.get(ctx, "/services/"+serviceID, query, nil) serverResp, err := cli.get(ctx, "/services/"+serviceID, query, nil)
if err != nil { if err != nil {
if serverResp.statusCode == http.StatusNotFound { return swarm.Service{}, nil, wrapResponseError(err, serverResp, "service", serviceID)
return swarm.Service{}, nil, serviceNotFoundError{serviceID}
}
return swarm.Service{}, nil, err
} }
defer ensureReaderClosed(serverResp) defer ensureReaderClosed(serverResp)

View file

@ -6,5 +6,5 @@ import "golang.org/x/net/context"
func (cli *Client) ServiceRemove(ctx context.Context, serviceID string) error { func (cli *Client) ServiceRemove(ctx context.Context, serviceID string) error {
resp, err := cli.delete(ctx, "/services/"+serviceID, nil, nil) resp, err := cli.delete(ctx, "/services/"+serviceID, nil, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return wrapResponseError(err, resp, "service", serviceID)
} }

View file

@ -8,6 +8,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@ -17,9 +18,17 @@ func TestServiceRemoveError(t *testing.T) {
} }
err := client.ServiceRemove(context.Background(), "service_id") err := client.ServiceRemove(context.Background(), "service_id")
if err == nil || err.Error() != "Error response from daemon: Server error" { assert.EqualError(t, err, "Error response from daemon: Server error")
t.Fatalf("expected a Server Error, got %v", err) }
func TestServiceRemoveNotFoundError(t *testing.T) {
client := &Client{
client: newMockClient(errorMock(http.StatusNotFound, "missing")),
} }
err := client.ServiceRemove(context.Background(), "service_id")
assert.EqualError(t, err, "Error: No such service: service_id")
assert.True(t, IsErrNotFound(err))
} }
func TestServiceRemove(t *testing.T) { func TestServiceRemove(t *testing.T) {

View file

@ -4,10 +4,8 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/swarm"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@ -15,10 +13,7 @@ import (
func (cli *Client) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) { func (cli *Client) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) {
serverResp, err := cli.get(ctx, "/tasks/"+taskID, nil, nil) serverResp, err := cli.get(ctx, "/tasks/"+taskID, nil, nil)
if err != nil { if err != nil {
if serverResp.statusCode == http.StatusNotFound { return swarm.Task{}, nil, wrapResponseError(err, serverResp, "task", taskID)
return swarm.Task{}, nil, taskNotFoundError{taskID}
}
return swarm.Task{}, nil, err
} }
defer ensureReaderClosed(serverResp) defer ensureReaderClosed(serverResp)

View file

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"net/http"
"path" "path"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -23,16 +22,13 @@ func (cli *Client) VolumeInspectWithRaw(ctx context.Context, volumeID string) (t
// request url will not contain a trailing / which calls the volume list API // request url will not contain a trailing / which calls the volume list API
// instead of volume inspect // instead of volume inspect
if volumeID == "" { if volumeID == "" {
return types.Volume{}, nil, volumeNotFoundError{volumeID} return types.Volume{}, nil, objectNotFoundError{object: "volume", id: volumeID}
} }
var volume types.Volume var volume types.Volume
resp, err := cli.get(ctx, path.Join("/volumes", volumeID), nil, nil) resp, err := cli.get(ctx, path.Join("/volumes", volumeID), nil, nil)
if err != nil { if err != nil {
if resp.statusCode == http.StatusNotFound { return volume, nil, wrapResponseError(err, resp, "volume", volumeID)
return volume, nil, volumeNotFoundError{volumeID}
}
return volume, nil, err
} }
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View file

@ -17,5 +17,5 @@ func (cli *Client) VolumeRemove(ctx context.Context, volumeID string, force bool
} }
resp, err := cli.delete(ctx, "/volumes/"+volumeID, query, nil) resp, err := cli.delete(ctx, "/volumes/"+volumeID, query, nil)
ensureReaderClosed(resp) ensureReaderClosed(resp)
return err return wrapResponseError(err, resp, "volume", volumeID)
} }

View file

@ -1617,7 +1617,7 @@ func (s *DockerSuite) TestContainerAPIDeleteWithEmptyName(c *check.C) {
defer cli.Close() defer cli.Close()
err = cli.ContainerRemove(context.Background(), "", types.ContainerRemoveOptions{}) err = cli.ContainerRemove(context.Background(), "", types.ContainerRemoveOptions{})
c.Assert(err.Error(), checker.Contains, "Error response from daemon: page not found") c.Assert(err.Error(), checker.Contains, "No such container")
} }
func (s *DockerSuite) TestContainerAPIStatsWithNetworkDisabled(c *check.C) { func (s *DockerSuite) TestContainerAPIStatsWithNetworkDisabled(c *check.C) {

View file

@ -55,10 +55,8 @@ func (s *DockerSwarmSuite) TestAPISwarmConfigsDelete(c *check.C) {
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
defer cli.Close() defer cli.Close()
expected := "no such config"
_, _, err = cli.ConfigInspectWithRaw(context.Background(), id) _, _, err = cli.ConfigInspectWithRaw(context.Background(), id)
c.Assert(err.Error(), checker.Contains, expected) c.Assert(err.Error(), checker.Contains, "No such config")
} }
func (s *DockerSwarmSuite) TestAPISwarmConfigsUpdate(c *check.C) { func (s *DockerSwarmSuite) TestAPISwarmConfigsUpdate(c *check.C) {

View file

@ -64,14 +64,12 @@ func (s *DockerSwarmSuite) TestAPISwarmSecretsDelete(c *check.C) {
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
defer cli.Close() defer cli.Close()
expected := "no such secret"
_, _, err = cli.SecretInspectWithRaw(context.Background(), id) _, _, err = cli.SecretInspectWithRaw(context.Background(), id)
c.Assert(err.Error(), checker.Contains, expected) c.Assert(err.Error(), checker.Contains, "No such secret")
id = "non-existing" id = "non-existing"
expected = "secret non-existing not found"
err = cli.SecretRemove(context.Background(), id) err = cli.SecretRemove(context.Background(), id)
c.Assert(err.Error(), checker.Contains, expected) c.Assert(err.Error(), checker.Contains, "No such secret: non-existing")
} }
func (s *DockerSwarmSuite) TestAPISwarmSecretsUpdate(c *check.C) { func (s *DockerSwarmSuite) TestAPISwarmSecretsUpdate(c *check.C) {