And fix remove calls to return a notFound error
Signed-off-by: Daniel Nephin <dnephin@docker.com>
... | ... |
@@ -2,7 +2,6 @@ package client |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
"encoding/json" |
5 |
- "net/http" |
|
6 | 5 |
"net/url" |
7 | 6 |
|
8 | 7 |
"github.com/docker/docker/api/types" |
... | ... |
@@ -20,10 +19,7 @@ func (cli *Client) CheckpointList(ctx context.Context, container string, options |
20 | 20 |
|
21 | 21 |
resp, err := cli.get(ctx, "/containers/"+container+"/checkpoints", query, nil) |
22 | 22 |
if err != nil { |
23 |
- if resp.statusCode == http.StatusNotFound { |
|
24 |
- return checkpoints, containerNotFoundError{container} |
|
25 |
- } |
|
26 |
- return checkpoints, err |
|
23 |
+ return checkpoints, wrapResponseError(err, resp, "container", container) |
|
27 | 24 |
} |
28 | 25 |
|
29 | 26 |
err = json.NewDecoder(resp.body).Decode(&checkpoints) |
... | ... |
@@ -4,7 +4,6 @@ import ( |
4 | 4 |
"bytes" |
5 | 5 |
"encoding/json" |
6 | 6 |
"io/ioutil" |
7 |
- "net/http" |
|
8 | 7 |
|
9 | 8 |
"github.com/docker/docker/api/types/swarm" |
10 | 9 |
"golang.org/x/net/context" |
... | ... |
@@ -17,10 +16,7 @@ func (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.C |
17 | 17 |
} |
18 | 18 |
resp, err := cli.get(ctx, "/configs/"+id, nil, nil) |
19 | 19 |
if err != nil { |
20 |
- if resp.statusCode == http.StatusNotFound { |
|
21 |
- return swarm.Config{}, nil, configNotFoundError{id} |
|
22 |
- } |
|
23 |
- return swarm.Config{}, nil, err |
|
20 |
+ return swarm.Config{}, nil, wrapResponseError(err, resp, "config", id) |
|
24 | 21 |
} |
25 | 22 |
defer ensureReaderClosed(resp) |
26 | 23 |
|
... | ... |
@@ -45,7 +45,7 @@ func (cli *Client) ContainerCreate(ctx context.Context, config *container.Config |
45 | 45 |
serverResp, err := cli.post(ctx, "/containers/create", query, body, nil) |
46 | 46 |
if err != nil { |
47 | 47 |
if serverResp.statusCode == 404 && strings.Contains(err.Error(), "No such image") { |
48 |
- return response, imageNotFoundError{config.Image} |
|
48 |
+ return response, objectNotFoundError{object: "image", id: config.Image} |
|
49 | 49 |
} |
50 | 50 |
return response, err |
51 | 51 |
} |
... | ... |
@@ -4,7 +4,6 @@ import ( |
4 | 4 |
"bytes" |
5 | 5 |
"encoding/json" |
6 | 6 |
"io/ioutil" |
7 |
- "net/http" |
|
8 | 7 |
"net/url" |
9 | 8 |
|
10 | 9 |
"github.com/docker/docker/api/types" |
... | ... |
@@ -15,10 +14,7 @@ import ( |
15 | 15 |
func (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) { |
16 | 16 |
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", nil, nil) |
17 | 17 |
if err != nil { |
18 |
- if serverResp.statusCode == http.StatusNotFound { |
|
19 |
- return types.ContainerJSON{}, containerNotFoundError{containerID} |
|
20 |
- } |
|
21 |
- return types.ContainerJSON{}, err |
|
18 |
+ return types.ContainerJSON{}, wrapResponseError(err, serverResp, "container", containerID) |
|
22 | 19 |
} |
23 | 20 |
|
24 | 21 |
var response types.ContainerJSON |
... | ... |
@@ -35,10 +31,7 @@ func (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID stri |
35 | 35 |
} |
36 | 36 |
serverResp, err := cli.get(ctx, "/containers/"+containerID+"/json", query, nil) |
37 | 37 |
if err != nil { |
38 |
- if serverResp.statusCode == http.StatusNotFound { |
|
39 |
- return types.ContainerJSON{}, nil, containerNotFoundError{containerID} |
|
40 |
- } |
|
41 |
- return types.ContainerJSON{}, nil, err |
|
38 |
+ return types.ContainerJSON{}, nil, wrapResponseError(err, serverResp, "container", containerID) |
|
42 | 39 |
} |
43 | 40 |
defer ensureReaderClosed(serverResp) |
44 | 41 |
|
... | ... |
@@ -23,5 +23,5 @@ func (cli *Client) ContainerRemove(ctx context.Context, containerID string, opti |
23 | 23 |
|
24 | 24 |
resp, err := cli.delete(ctx, "/containers/"+containerID, query, nil) |
25 | 25 |
ensureReaderClosed(resp) |
26 |
- return err |
|
26 |
+ return wrapResponseError(err, resp, "container", containerID) |
|
27 | 27 |
} |
... | ... |
@@ -9,6 +9,7 @@ import ( |
9 | 9 |
"testing" |
10 | 10 |
|
11 | 11 |
"github.com/docker/docker/api/types" |
12 |
+ "github.com/stretchr/testify/assert" |
|
12 | 13 |
"golang.org/x/net/context" |
13 | 14 |
) |
14 | 15 |
|
... | ... |
@@ -17,9 +18,16 @@ func TestContainerRemoveError(t *testing.T) { |
17 | 17 |
client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), |
18 | 18 |
} |
19 | 19 |
err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{}) |
20 |
- if err == nil || err.Error() != "Error response from daemon: Server error" { |
|
21 |
- t.Fatalf("expected a Server Error, got %v", err) |
|
20 |
+ assert.EqualError(t, err, "Error response from daemon: Server error") |
|
21 |
+} |
|
22 |
+ |
|
23 |
+func TestContainerRemoveNotFoundError(t *testing.T) { |
|
24 |
+ client := &Client{ |
|
25 |
+ client: newMockClient(errorMock(http.StatusNotFound, "missing")), |
|
22 | 26 |
} |
27 |
+ err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{}) |
|
28 |
+ assert.EqualError(t, err, "Error: No such container: container_id") |
|
29 |
+ assert.True(t, IsErrNotFound(err)) |
|
23 | 30 |
} |
24 | 31 |
|
25 | 32 |
func TestContainerRemove(t *testing.T) { |
... | ... |
@@ -53,7 +61,5 @@ func TestContainerRemove(t *testing.T) { |
53 | 53 |
RemoveVolumes: true, |
54 | 54 |
Force: true, |
55 | 55 |
}) |
56 |
- if err != nil { |
|
57 |
- t.Fatal(err) |
|
58 |
- } |
|
56 |
+ assert.NoError(t, err) |
|
59 | 57 |
} |
... | ... |
@@ -3,6 +3,8 @@ package client |
3 | 3 |
import ( |
4 | 4 |
"fmt" |
5 | 5 |
|
6 |
+ "net/http" |
|
7 |
+ |
|
6 | 8 |
"github.com/docker/docker/api/types/versions" |
7 | 9 |
"github.com/pkg/errors" |
8 | 10 |
) |
... | ... |
@@ -43,19 +45,28 @@ func IsErrNotFound(err error) bool { |
43 | 43 |
return ok && te.NotFound() |
44 | 44 |
} |
45 | 45 |
|
46 |
-// imageNotFoundError implements an error returned when an image is not in the docker host. |
|
47 |
-type imageNotFoundError struct { |
|
48 |
- imageID string |
|
46 |
+type objectNotFoundError struct { |
|
47 |
+ object string |
|
48 |
+ id string |
|
49 | 49 |
} |
50 | 50 |
|
51 |
-// NotFound indicates that this error type is of NotFound |
|
52 |
-func (e imageNotFoundError) NotFound() bool { |
|
51 |
+func (e objectNotFoundError) NotFound() bool { |
|
53 | 52 |
return true |
54 | 53 |
} |
55 | 54 |
|
56 |
-// Error returns a string representation of an imageNotFoundError |
|
57 |
-func (e imageNotFoundError) Error() string { |
|
58 |
- return fmt.Sprintf("Error: No such image: %s", e.imageID) |
|
55 |
+func (e objectNotFoundError) Error() string { |
|
56 |
+ return fmt.Sprintf("Error: No such %s: %s", e.object, e.id) |
|
57 |
+} |
|
58 |
+ |
|
59 |
+func wrapResponseError(err error, resp serverResponse, object, id string) error { |
|
60 |
+ switch { |
|
61 |
+ case err == nil: |
|
62 |
+ return nil |
|
63 |
+ case resp.statusCode == http.StatusNotFound: |
|
64 |
+ return objectNotFoundError{object: object, id: id} |
|
65 |
+ default: |
|
66 |
+ return err |
|
67 |
+ } |
|
59 | 68 |
} |
60 | 69 |
|
61 | 70 |
// IsErrImageNotFound returns true if the error is caused |
... | ... |
@@ -66,21 +77,6 @@ func IsErrImageNotFound(err error) bool { |
66 | 66 |
return IsErrNotFound(err) |
67 | 67 |
} |
68 | 68 |
|
69 |
-// containerNotFoundError implements an error returned when a container is not in the docker host. |
|
70 |
-type containerNotFoundError struct { |
|
71 |
- containerID string |
|
72 |
-} |
|
73 |
- |
|
74 |
-// NotFound indicates that this error type is of NotFound |
|
75 |
-func (e containerNotFoundError) NotFound() bool { |
|
76 |
- return true |
|
77 |
-} |
|
78 |
- |
|
79 |
-// Error returns a string representation of a containerNotFoundError |
|
80 |
-func (e containerNotFoundError) Error() string { |
|
81 |
- return fmt.Sprintf("Error: No such container: %s", e.containerID) |
|
82 |
-} |
|
83 |
- |
|
84 | 69 |
// IsErrContainerNotFound returns true if the error is caused |
85 | 70 |
// when a container is not found in the docker host. |
86 | 71 |
// |
... | ... |
@@ -89,21 +85,6 @@ func IsErrContainerNotFound(err error) bool { |
89 | 89 |
return IsErrNotFound(err) |
90 | 90 |
} |
91 | 91 |
|
92 |
-// networkNotFoundError implements an error returned when a network is not in the docker host. |
|
93 |
-type networkNotFoundError struct { |
|
94 |
- networkID string |
|
95 |
-} |
|
96 |
- |
|
97 |
-// NotFound indicates that this error type is of NotFound |
|
98 |
-func (e networkNotFoundError) NotFound() bool { |
|
99 |
- return true |
|
100 |
-} |
|
101 |
- |
|
102 |
-// Error returns a string representation of a networkNotFoundError |
|
103 |
-func (e networkNotFoundError) Error() string { |
|
104 |
- return fmt.Sprintf("Error: No such network: %s", e.networkID) |
|
105 |
-} |
|
106 |
- |
|
107 | 92 |
// IsErrNetworkNotFound returns true if the error is caused |
108 | 93 |
// when a network is not found in the docker host. |
109 | 94 |
// |
... | ... |
@@ -112,21 +93,6 @@ func IsErrNetworkNotFound(err error) bool { |
112 | 112 |
return IsErrNotFound(err) |
113 | 113 |
} |
114 | 114 |
|
115 |
-// volumeNotFoundError implements an error returned when a volume is not in the docker host. |
|
116 |
-type volumeNotFoundError struct { |
|
117 |
- volumeID string |
|
118 |
-} |
|
119 |
- |
|
120 |
-// NotFound indicates that this error type is of NotFound |
|
121 |
-func (e volumeNotFoundError) NotFound() bool { |
|
122 |
- return true |
|
123 |
-} |
|
124 |
- |
|
125 |
-// Error returns a string representation of a volumeNotFoundError |
|
126 |
-func (e volumeNotFoundError) Error() string { |
|
127 |
- return fmt.Sprintf("Error: No such volume: %s", e.volumeID) |
|
128 |
-} |
|
129 |
- |
|
130 | 115 |
// IsErrVolumeNotFound returns true if the error is caused |
131 | 116 |
// when a volume is not found in the docker host. |
132 | 117 |
// |
... | ... |
@@ -152,43 +118,12 @@ func IsErrUnauthorized(err error) bool { |
152 | 152 |
return ok |
153 | 153 |
} |
154 | 154 |
|
155 |
-// nodeNotFoundError implements an error returned when a node is not found. |
|
156 |
-type nodeNotFoundError struct { |
|
157 |
- nodeID string |
|
158 |
-} |
|
159 |
- |
|
160 |
-// Error returns a string representation of a nodeNotFoundError |
|
161 |
-func (e nodeNotFoundError) Error() string { |
|
162 |
- return fmt.Sprintf("Error: No such node: %s", e.nodeID) |
|
163 |
-} |
|
164 |
- |
|
165 |
-// NotFound indicates that this error type is of NotFound |
|
166 |
-func (e nodeNotFoundError) NotFound() bool { |
|
167 |
- return true |
|
168 |
-} |
|
169 |
- |
|
170 | 155 |
// IsErrNodeNotFound returns true if the error is caused |
171 | 156 |
// when a node is not found. |
172 | 157 |
// |
173 | 158 |
// Deprecated: Use IsErrNotFound |
174 | 159 |
func IsErrNodeNotFound(err error) bool { |
175 |
- _, ok := err.(nodeNotFoundError) |
|
176 |
- return ok |
|
177 |
-} |
|
178 |
- |
|
179 |
-// serviceNotFoundError implements an error returned when a service is not found. |
|
180 |
-type serviceNotFoundError struct { |
|
181 |
- serviceID string |
|
182 |
-} |
|
183 |
- |
|
184 |
-// Error returns a string representation of a serviceNotFoundError |
|
185 |
-func (e serviceNotFoundError) Error() string { |
|
186 |
- return fmt.Sprintf("Error: No such service: %s", e.serviceID) |
|
187 |
-} |
|
188 |
- |
|
189 |
-// NotFound indicates that this error type is of NotFound |
|
190 |
-func (e serviceNotFoundError) NotFound() bool { |
|
191 |
- return true |
|
160 |
+ return IsErrNotFound(err) |
|
192 | 161 |
} |
193 | 162 |
|
194 | 163 |
// IsErrServiceNotFound returns true if the error is caused |
... | ... |
@@ -196,23 +131,7 @@ func (e serviceNotFoundError) NotFound() bool { |
196 | 196 |
// |
197 | 197 |
// Deprecated: Use IsErrNotFound |
198 | 198 |
func IsErrServiceNotFound(err error) bool { |
199 |
- _, ok := err.(serviceNotFoundError) |
|
200 |
- return ok |
|
201 |
-} |
|
202 |
- |
|
203 |
-// taskNotFoundError implements an error returned when a task is not found. |
|
204 |
-type taskNotFoundError struct { |
|
205 |
- taskID string |
|
206 |
-} |
|
207 |
- |
|
208 |
-// Error returns a string representation of a taskNotFoundError |
|
209 |
-func (e taskNotFoundError) Error() string { |
|
210 |
- return fmt.Sprintf("Error: No such task: %s", e.taskID) |
|
211 |
-} |
|
212 |
- |
|
213 |
-// NotFound indicates that this error type is of NotFound |
|
214 |
-func (e taskNotFoundError) NotFound() bool { |
|
215 |
- return true |
|
199 |
+ return IsErrNotFound(err) |
|
216 | 200 |
} |
217 | 201 |
|
218 | 202 |
// IsErrTaskNotFound returns true if the error is caused |
... | ... |
@@ -220,8 +139,7 @@ func (e taskNotFoundError) NotFound() bool { |
220 | 220 |
// |
221 | 221 |
// Deprecated: Use IsErrNotFound |
222 | 222 |
func IsErrTaskNotFound(err error) bool { |
223 |
- _, ok := err.(taskNotFoundError) |
|
224 |
- return ok |
|
223 |
+ return IsErrNotFound(err) |
|
225 | 224 |
} |
226 | 225 |
|
227 | 226 |
type pluginPermissionDenied struct { |
... | ... |
@@ -248,43 +166,12 @@ func (cli *Client) NewVersionError(APIrequired, feature string) error { |
248 | 248 |
return nil |
249 | 249 |
} |
250 | 250 |
|
251 |
-// secretNotFoundError implements an error returned when a secret is not found. |
|
252 |
-type secretNotFoundError struct { |
|
253 |
- name string |
|
254 |
-} |
|
255 |
- |
|
256 |
-// Error returns a string representation of a secretNotFoundError |
|
257 |
-func (e secretNotFoundError) Error() string { |
|
258 |
- return fmt.Sprintf("Error: no such secret: %s", e.name) |
|
259 |
-} |
|
260 |
- |
|
261 |
-// NotFound indicates that this error type is of NotFound |
|
262 |
-func (e secretNotFoundError) NotFound() bool { |
|
263 |
- return true |
|
264 |
-} |
|
265 |
- |
|
266 | 251 |
// IsErrSecretNotFound returns true if the error is caused |
267 | 252 |
// when a secret is not found. |
268 | 253 |
// |
269 | 254 |
// Deprecated: Use IsErrNotFound |
270 | 255 |
func IsErrSecretNotFound(err error) bool { |
271 |
- _, ok := err.(secretNotFoundError) |
|
272 |
- return ok |
|
273 |
-} |
|
274 |
- |
|
275 |
-// configNotFoundError implements an error returned when a config is not found. |
|
276 |
-type configNotFoundError struct { |
|
277 |
- name string |
|
278 |
-} |
|
279 |
- |
|
280 |
-// Error returns a string representation of a configNotFoundError |
|
281 |
-func (e configNotFoundError) Error() string { |
|
282 |
- return fmt.Sprintf("Error: no such config: %s", e.name) |
|
283 |
-} |
|
284 |
- |
|
285 |
-// NotFound indicates that this error type is of NotFound |
|
286 |
-func (e configNotFoundError) NotFound() bool { |
|
287 |
- return true |
|
256 |
+ return IsErrNotFound(err) |
|
288 | 257 |
} |
289 | 258 |
|
290 | 259 |
// IsErrConfigNotFound returns true if the error is caused |
... | ... |
@@ -292,23 +179,7 @@ func (e configNotFoundError) NotFound() bool { |
292 | 292 |
// |
293 | 293 |
// Deprecated: Use IsErrNotFound |
294 | 294 |
func IsErrConfigNotFound(err error) bool { |
295 |
- _, ok := err.(configNotFoundError) |
|
296 |
- return ok |
|
297 |
-} |
|
298 |
- |
|
299 |
-// pluginNotFoundError implements an error returned when a plugin is not in the docker host. |
|
300 |
-type pluginNotFoundError struct { |
|
301 |
- name string |
|
302 |
-} |
|
303 |
- |
|
304 |
-// NotFound indicates that this error type is of NotFound |
|
305 |
-func (e pluginNotFoundError) NotFound() bool { |
|
306 |
- return true |
|
307 |
-} |
|
308 |
- |
|
309 |
-// Error returns a string representation of a pluginNotFoundError |
|
310 |
-func (e pluginNotFoundError) Error() string { |
|
311 |
- return fmt.Sprintf("Error: No such plugin: %s", e.name) |
|
295 |
+ return IsErrNotFound(err) |
|
312 | 296 |
} |
313 | 297 |
|
314 | 298 |
// IsErrPluginNotFound returns true if the error is caused |
... | ... |
@@ -4,7 +4,6 @@ import ( |
4 | 4 |
"bytes" |
5 | 5 |
"encoding/json" |
6 | 6 |
"io/ioutil" |
7 |
- "net/http" |
|
8 | 7 |
|
9 | 8 |
"github.com/docker/docker/api/types" |
10 | 9 |
"golang.org/x/net/context" |
... | ... |
@@ -14,10 +13,7 @@ import ( |
14 | 14 |
func (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) { |
15 | 15 |
serverResp, err := cli.get(ctx, "/images/"+imageID+"/json", nil, nil) |
16 | 16 |
if err != nil { |
17 |
- if serverResp.statusCode == http.StatusNotFound { |
|
18 |
- return types.ImageInspect{}, nil, imageNotFoundError{imageID} |
|
19 |
- } |
|
20 |
- return types.ImageInspect{}, nil, err |
|
17 |
+ return types.ImageInspect{}, nil, wrapResponseError(err, serverResp, "image", imageID) |
|
21 | 18 |
} |
22 | 19 |
defer ensureReaderClosed(serverResp) |
23 | 20 |
|
... | ... |
@@ -2,7 +2,6 @@ package client |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
"encoding/json" |
5 |
- "net/http" |
|
6 | 5 |
"net/url" |
7 | 6 |
|
8 | 7 |
"github.com/docker/docker/api/types" |
... | ... |
@@ -20,15 +19,12 @@ func (cli *Client) ImageRemove(ctx context.Context, imageID string, options type |
20 | 20 |
query.Set("noprune", "1") |
21 | 21 |
} |
22 | 22 |
|
23 |
+ var dels []types.ImageDeleteResponseItem |
|
23 | 24 |
resp, err := cli.delete(ctx, "/images/"+imageID, query, nil) |
24 | 25 |
if err != nil { |
25 |
- if resp.statusCode == http.StatusNotFound { |
|
26 |
- return nil, imageNotFoundError{imageID} |
|
27 |
- } |
|
28 |
- return nil, err |
|
26 |
+ return dels, wrapResponseError(err, resp, "image", imageID) |
|
29 | 27 |
} |
30 | 28 |
|
31 |
- var dels []types.ImageDeleteResponseItem |
|
32 | 29 |
err = json.NewDecoder(resp.body).Decode(&dels) |
33 | 30 |
ensureReaderClosed(resp) |
34 | 31 |
return dels, err |
... | ... |
@@ -10,6 +10,7 @@ import ( |
10 | 10 |
"testing" |
11 | 11 |
|
12 | 12 |
"github.com/docker/docker/api/types" |
13 |
+ "github.com/stretchr/testify/assert" |
|
13 | 14 |
"golang.org/x/net/context" |
14 | 15 |
) |
15 | 16 |
|
... | ... |
@@ -19,20 +20,17 @@ func TestImageRemoveError(t *testing.T) { |
19 | 19 |
} |
20 | 20 |
|
21 | 21 |
_, err := client.ImageRemove(context.Background(), "image_id", types.ImageRemoveOptions{}) |
22 |
- if err == nil || err.Error() != "Error response from daemon: Server error" { |
|
23 |
- t.Fatalf("expected a Server Error, got %v", err) |
|
24 |
- } |
|
22 |
+ assert.EqualError(t, err, "Error response from daemon: Server error") |
|
25 | 23 |
} |
26 | 24 |
|
27 | 25 |
func TestImageRemoveImageNotFound(t *testing.T) { |
28 | 26 |
client := &Client{ |
29 |
- client: newMockClient(errorMock(http.StatusNotFound, "Server error")), |
|
27 |
+ client: newMockClient(errorMock(http.StatusNotFound, "missing")), |
|
30 | 28 |
} |
31 | 29 |
|
32 | 30 |
_, err := client.ImageRemove(context.Background(), "unknown", types.ImageRemoveOptions{}) |
33 |
- if err == nil || !IsErrNotFound(err) { |
|
34 |
- t.Fatalf("expected an imageNotFoundError error, got %v", err) |
|
35 |
- } |
|
31 |
+ assert.EqualError(t, err, "Error: No such image: unknown") |
|
32 |
+ assert.True(t, IsErrNotFound(err)) |
|
36 | 33 |
} |
37 | 34 |
|
38 | 35 |
func TestImageRemove(t *testing.T) { |
... | ... |
@@ -4,7 +4,6 @@ import ( |
4 | 4 |
"bytes" |
5 | 5 |
"encoding/json" |
6 | 6 |
"io/ioutil" |
7 |
- "net/http" |
|
8 | 7 |
"net/url" |
9 | 8 |
|
10 | 9 |
"github.com/docker/docker/api/types" |
... | ... |
@@ -33,10 +32,7 @@ func (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string, |
33 | 33 |
} |
34 | 34 |
resp, err = cli.get(ctx, "/networks/"+networkID, query, nil) |
35 | 35 |
if err != nil { |
36 |
- if resp.statusCode == http.StatusNotFound { |
|
37 |
- return networkResource, nil, networkNotFoundError{networkID} |
|
38 |
- } |
|
39 |
- return networkResource, nil, err |
|
36 |
+ return networkResource, nil, wrapResponseError(err, resp, "network", networkID) |
|
40 | 37 |
} |
41 | 38 |
defer ensureReaderClosed(resp) |
42 | 39 |
|
... | ... |
@@ -21,20 +21,17 @@ func TestNetworkInspectError(t *testing.T) { |
21 | 21 |
} |
22 | 22 |
|
23 | 23 |
_, err := client.NetworkInspect(context.Background(), "nothing", types.NetworkInspectOptions{}) |
24 |
- if err == nil || err.Error() != "Error response from daemon: Server error" { |
|
25 |
- t.Fatalf("expected a Server Error, got %v", err) |
|
26 |
- } |
|
24 |
+ assert.EqualError(t, err, "Error response from daemon: Server error") |
|
27 | 25 |
} |
28 | 26 |
|
29 |
-func TestNetworkInspectContainerNotFound(t *testing.T) { |
|
27 |
+func TestNetworkInspectNotFoundError(t *testing.T) { |
|
30 | 28 |
client := &Client{ |
31 |
- client: newMockClient(errorMock(http.StatusNotFound, "Server error")), |
|
29 |
+ client: newMockClient(errorMock(http.StatusNotFound, "missing")), |
|
32 | 30 |
} |
33 | 31 |
|
34 | 32 |
_, err := client.NetworkInspect(context.Background(), "unknown", types.NetworkInspectOptions{}) |
35 |
- if err == nil || !IsErrNetworkNotFound(err) { |
|
36 |
- t.Fatalf("expected a networkNotFound error, got %v", err) |
|
37 |
- } |
|
33 |
+ assert.EqualError(t, err, "Error: No such network: unknown") |
|
34 |
+ assert.True(t, IsErrNotFound(err)) |
|
38 | 35 |
} |
39 | 36 |
|
40 | 37 |
func TestNetworkInspect(t *testing.T) { |
... | ... |
@@ -6,5 +6,5 @@ import "golang.org/x/net/context" |
6 | 6 |
func (cli *Client) NetworkRemove(ctx context.Context, networkID string) error { |
7 | 7 |
resp, err := cli.delete(ctx, "/networks/"+networkID, nil, nil) |
8 | 8 |
ensureReaderClosed(resp) |
9 |
- return err |
|
9 |
+ return wrapResponseError(err, resp, "network", networkID) |
|
10 | 10 |
} |
... | ... |
@@ -4,7 +4,6 @@ import ( |
4 | 4 |
"bytes" |
5 | 5 |
"encoding/json" |
6 | 6 |
"io/ioutil" |
7 |
- "net/http" |
|
8 | 7 |
|
9 | 8 |
"github.com/docker/docker/api/types/swarm" |
10 | 9 |
"golang.org/x/net/context" |
... | ... |
@@ -14,10 +13,7 @@ import ( |
14 | 14 |
func (cli *Client) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) { |
15 | 15 |
serverResp, err := cli.get(ctx, "/nodes/"+nodeID, nil, nil) |
16 | 16 |
if err != nil { |
17 |
- if serverResp.statusCode == http.StatusNotFound { |
|
18 |
- return swarm.Node{}, nil, nodeNotFoundError{nodeID} |
|
19 |
- } |
|
20 |
- return swarm.Node{}, nil, err |
|
17 |
+ return swarm.Node{}, nil, wrapResponseError(err, serverResp, "node", nodeID) |
|
21 | 18 |
} |
22 | 19 |
defer ensureReaderClosed(serverResp) |
23 | 20 |
|
... | ... |
@@ -4,7 +4,6 @@ import ( |
4 | 4 |
"bytes" |
5 | 5 |
"encoding/json" |
6 | 6 |
"io/ioutil" |
7 |
- "net/http" |
|
8 | 7 |
|
9 | 8 |
"github.com/docker/docker/api/types" |
10 | 9 |
"golang.org/x/net/context" |
... | ... |
@@ -14,10 +13,7 @@ import ( |
14 | 14 |
func (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) { |
15 | 15 |
resp, err := cli.get(ctx, "/plugins/"+name+"/json", nil, nil) |
16 | 16 |
if err != nil { |
17 |
- if resp.statusCode == http.StatusNotFound { |
|
18 |
- return nil, nil, pluginNotFoundError{name} |
|
19 |
- } |
|
20 |
- return nil, nil, err |
|
17 |
+ return nil, nil, wrapResponseError(err, resp, "plugin", name) |
|
21 | 18 |
} |
22 | 19 |
|
23 | 20 |
defer ensureReaderClosed(resp) |
... | ... |
@@ -203,7 +203,7 @@ func (cli *Client) checkResponseErr(serverResp serverResponse) error { |
203 | 203 |
return err |
204 | 204 |
} |
205 | 205 |
if len(body) == 0 { |
206 |
- 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) |
|
206 |
+ 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) |
|
207 | 207 |
} |
208 | 208 |
|
209 | 209 |
var ct string |
... | ... |
@@ -4,7 +4,6 @@ import ( |
4 | 4 |
"bytes" |
5 | 5 |
"encoding/json" |
6 | 6 |
"io/ioutil" |
7 |
- "net/http" |
|
8 | 7 |
|
9 | 8 |
"github.com/docker/docker/api/types/swarm" |
10 | 9 |
"golang.org/x/net/context" |
... | ... |
@@ -17,10 +16,7 @@ func (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.S |
17 | 17 |
} |
18 | 18 |
resp, err := cli.get(ctx, "/secrets/"+id, nil, nil) |
19 | 19 |
if err != nil { |
20 |
- if resp.statusCode == http.StatusNotFound { |
|
21 |
- return swarm.Secret{}, nil, secretNotFoundError{id} |
|
22 |
- } |
|
23 |
- return swarm.Secret{}, nil, err |
|
20 |
+ return swarm.Secret{}, nil, wrapResponseError(err, resp, "secret", id) |
|
24 | 21 |
} |
25 | 22 |
defer ensureReaderClosed(resp) |
26 | 23 |
|
... | ... |
@@ -5,7 +5,6 @@ import ( |
5 | 5 |
"encoding/json" |
6 | 6 |
"fmt" |
7 | 7 |
"io/ioutil" |
8 |
- "net/http" |
|
9 | 8 |
"net/url" |
10 | 9 |
|
11 | 10 |
"github.com/docker/docker/api/types" |
... | ... |
@@ -19,10 +18,7 @@ func (cli *Client) ServiceInspectWithRaw(ctx context.Context, serviceID string, |
19 | 19 |
query.Set("insertDefaults", fmt.Sprintf("%v", opts.InsertDefaults)) |
20 | 20 |
serverResp, err := cli.get(ctx, "/services/"+serviceID, query, nil) |
21 | 21 |
if err != nil { |
22 |
- if serverResp.statusCode == http.StatusNotFound { |
|
23 |
- return swarm.Service{}, nil, serviceNotFoundError{serviceID} |
|
24 |
- } |
|
25 |
- return swarm.Service{}, nil, err |
|
22 |
+ return swarm.Service{}, nil, wrapResponseError(err, serverResp, "service", serviceID) |
|
26 | 23 |
} |
27 | 24 |
defer ensureReaderClosed(serverResp) |
28 | 25 |
|
... | ... |
@@ -6,5 +6,5 @@ import "golang.org/x/net/context" |
6 | 6 |
func (cli *Client) ServiceRemove(ctx context.Context, serviceID string) error { |
7 | 7 |
resp, err := cli.delete(ctx, "/services/"+serviceID, nil, nil) |
8 | 8 |
ensureReaderClosed(resp) |
9 |
- return err |
|
9 |
+ return wrapResponseError(err, resp, "service", serviceID) |
|
10 | 10 |
} |
... | ... |
@@ -8,6 +8,7 @@ import ( |
8 | 8 |
"strings" |
9 | 9 |
"testing" |
10 | 10 |
|
11 |
+ "github.com/stretchr/testify/assert" |
|
11 | 12 |
"golang.org/x/net/context" |
12 | 13 |
) |
13 | 14 |
|
... | ... |
@@ -17,9 +18,17 @@ func TestServiceRemoveError(t *testing.T) { |
17 | 17 |
} |
18 | 18 |
|
19 | 19 |
err := client.ServiceRemove(context.Background(), "service_id") |
20 |
- if err == nil || err.Error() != "Error response from daemon: Server error" { |
|
21 |
- t.Fatalf("expected a Server Error, got %v", err) |
|
20 |
+ assert.EqualError(t, err, "Error response from daemon: Server error") |
|
21 |
+} |
|
22 |
+ |
|
23 |
+func TestServiceRemoveNotFoundError(t *testing.T) { |
|
24 |
+ client := &Client{ |
|
25 |
+ client: newMockClient(errorMock(http.StatusNotFound, "missing")), |
|
22 | 26 |
} |
27 |
+ |
|
28 |
+ err := client.ServiceRemove(context.Background(), "service_id") |
|
29 |
+ assert.EqualError(t, err, "Error: No such service: service_id") |
|
30 |
+ assert.True(t, IsErrNotFound(err)) |
|
23 | 31 |
} |
24 | 32 |
|
25 | 33 |
func TestServiceRemove(t *testing.T) { |
... | ... |
@@ -4,10 +4,8 @@ import ( |
4 | 4 |
"bytes" |
5 | 5 |
"encoding/json" |
6 | 6 |
"io/ioutil" |
7 |
- "net/http" |
|
8 | 7 |
|
9 | 8 |
"github.com/docker/docker/api/types/swarm" |
10 |
- |
|
11 | 9 |
"golang.org/x/net/context" |
12 | 10 |
) |
13 | 11 |
|
... | ... |
@@ -15,10 +13,7 @@ import ( |
15 | 15 |
func (cli *Client) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) { |
16 | 16 |
serverResp, err := cli.get(ctx, "/tasks/"+taskID, nil, nil) |
17 | 17 |
if err != nil { |
18 |
- if serverResp.statusCode == http.StatusNotFound { |
|
19 |
- return swarm.Task{}, nil, taskNotFoundError{taskID} |
|
20 |
- } |
|
21 |
- return swarm.Task{}, nil, err |
|
18 |
+ return swarm.Task{}, nil, wrapResponseError(err, serverResp, "task", taskID) |
|
22 | 19 |
} |
23 | 20 |
defer ensureReaderClosed(serverResp) |
24 | 21 |
|
... | ... |
@@ -4,7 +4,6 @@ import ( |
4 | 4 |
"bytes" |
5 | 5 |
"encoding/json" |
6 | 6 |
"io/ioutil" |
7 |
- "net/http" |
|
8 | 7 |
"path" |
9 | 8 |
|
10 | 9 |
"github.com/docker/docker/api/types" |
... | ... |
@@ -23,16 +22,13 @@ func (cli *Client) VolumeInspectWithRaw(ctx context.Context, volumeID string) (t |
23 | 23 |
// request url will not contain a trailing / which calls the volume list API |
24 | 24 |
// instead of volume inspect |
25 | 25 |
if volumeID == "" { |
26 |
- return types.Volume{}, nil, volumeNotFoundError{volumeID} |
|
26 |
+ return types.Volume{}, nil, objectNotFoundError{object: "volume", id: volumeID} |
|
27 | 27 |
} |
28 | 28 |
|
29 | 29 |
var volume types.Volume |
30 | 30 |
resp, err := cli.get(ctx, path.Join("/volumes", volumeID), nil, nil) |
31 | 31 |
if err != nil { |
32 |
- if resp.statusCode == http.StatusNotFound { |
|
33 |
- return volume, nil, volumeNotFoundError{volumeID} |
|
34 |
- } |
|
35 |
- return volume, nil, err |
|
32 |
+ return volume, nil, wrapResponseError(err, resp, "volume", volumeID) |
|
36 | 33 |
} |
37 | 34 |
defer ensureReaderClosed(resp) |
38 | 35 |
|
... | ... |
@@ -1617,7 +1617,7 @@ func (s *DockerSuite) TestContainerAPIDeleteWithEmptyName(c *check.C) { |
1617 | 1617 |
defer cli.Close() |
1618 | 1618 |
|
1619 | 1619 |
err = cli.ContainerRemove(context.Background(), "", types.ContainerRemoveOptions{}) |
1620 |
- c.Assert(err.Error(), checker.Contains, "Error response from daemon: page not found") |
|
1620 |
+ c.Assert(err.Error(), checker.Contains, "No such container") |
|
1621 | 1621 |
} |
1622 | 1622 |
|
1623 | 1623 |
func (s *DockerSuite) TestContainerAPIStatsWithNetworkDisabled(c *check.C) { |
... | ... |
@@ -55,10 +55,8 @@ func (s *DockerSwarmSuite) TestAPISwarmConfigsDelete(c *check.C) { |
55 | 55 |
c.Assert(err, checker.IsNil) |
56 | 56 |
defer cli.Close() |
57 | 57 |
|
58 |
- expected := "no such config" |
|
59 |
- |
|
60 | 58 |
_, _, err = cli.ConfigInspectWithRaw(context.Background(), id) |
61 |
- c.Assert(err.Error(), checker.Contains, expected) |
|
59 |
+ c.Assert(err.Error(), checker.Contains, "No such config") |
|
62 | 60 |
} |
63 | 61 |
|
64 | 62 |
func (s *DockerSwarmSuite) TestAPISwarmConfigsUpdate(c *check.C) { |
... | ... |
@@ -64,14 +64,12 @@ func (s *DockerSwarmSuite) TestAPISwarmSecretsDelete(c *check.C) { |
64 | 64 |
c.Assert(err, checker.IsNil) |
65 | 65 |
defer cli.Close() |
66 | 66 |
|
67 |
- expected := "no such secret" |
|
68 | 67 |
_, _, err = cli.SecretInspectWithRaw(context.Background(), id) |
69 |
- c.Assert(err.Error(), checker.Contains, expected) |
|
68 |
+ c.Assert(err.Error(), checker.Contains, "No such secret") |
|
70 | 69 |
|
71 | 70 |
id = "non-existing" |
72 |
- expected = "secret non-existing not found" |
|
73 | 71 |
err = cli.SecretRemove(context.Background(), id) |
74 |
- c.Assert(err.Error(), checker.Contains, expected) |
|
72 |
+ c.Assert(err.Error(), checker.Contains, "No such secret: non-existing") |
|
75 | 73 |
} |
76 | 74 |
|
77 | 75 |
func (s *DockerSwarmSuite) TestAPISwarmSecretsUpdate(c *check.C) { |