Skip to content

Commit f727cdb

Browse files
committed
Add HTTP status code and error type conversion
Signed-off-by: Derek McGowan <[email protected]>
1 parent 9854dc7 commit f727cdb

2 files changed

Lines changed: 93 additions & 0 deletions

File tree

grpc_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ func TestGRPCRoundTrip(t *testing.T) {
8888
cause: ErrNotModified,
8989
str: "everything is the same: not modified",
9090
},
91+
{
92+
input: fmt.Errorf("odd HTTP response: %w", FromHTTP(418)),
93+
cause: errUnexpectedStatus{418},
94+
str: "odd HTTP response: unexpected status 418",
95+
},
9196
} {
9297
t.Run(testcase.input.Error(), func(t *testing.T) {
9398
t.Logf("input: %v", testcase.input)

http.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package errdefs
18+
19+
import (
20+
"errors"
21+
"net/http"
22+
)
23+
24+
// FromHTTP returns the error best matching the HTTP status code
25+
func FromHTTP(statusCode int) error {
26+
switch statusCode {
27+
case http.StatusNotFound:
28+
return ErrNotFound
29+
case http.StatusBadRequest:
30+
return ErrInvalidArgument
31+
case http.StatusConflict:
32+
return ErrConflict
33+
case http.StatusPreconditionFailed:
34+
return ErrFailedPrecondition
35+
case http.StatusUnauthorized:
36+
return ErrUnauthenticated
37+
case http.StatusForbidden:
38+
return ErrPermissionDenied
39+
case http.StatusNotModified:
40+
return ErrNotModified
41+
case http.StatusTooManyRequests:
42+
return ErrResourceExhausted
43+
case http.StatusInternalServerError:
44+
return ErrInternal
45+
case http.StatusNotImplemented:
46+
return ErrNotImplemented
47+
case http.StatusServiceUnavailable:
48+
return ErrUnavailable
49+
default:
50+
return errUnexpectedStatus{statusCode}
51+
}
52+
}
53+
54+
// ToHTTP returns the best status code for the given error
55+
func ToHTTP(err error) int {
56+
switch {
57+
case IsNotFound(err):
58+
return http.StatusNotFound
59+
case IsInvalidArgument(err):
60+
return http.StatusBadRequest
61+
case IsConflict(err):
62+
return http.StatusConflict
63+
case IsNotModified(err):
64+
return http.StatusNotModified
65+
case IsFailedPrecondition(err):
66+
return http.StatusPreconditionFailed
67+
case IsUnauthorized(err):
68+
return http.StatusUnauthorized
69+
case IsPermissionDenied(err):
70+
return http.StatusForbidden
71+
case IsResourceExhausted(err):
72+
return http.StatusTooManyRequests
73+
case IsInternal(err):
74+
return http.StatusInternalServerError
75+
case IsNotImplemented(err):
76+
return http.StatusNotImplemented
77+
case IsUnavailable(err):
78+
return http.StatusServiceUnavailable
79+
case IsUnknown(err):
80+
var unexpected errUnexpectedStatus
81+
if errors.As(err, &unexpected) && unexpected.status >= 200 && unexpected.status < 600 {
82+
return unexpected.status
83+
}
84+
return http.StatusInternalServerError
85+
default:
86+
return http.StatusInternalServerError
87+
}
88+
}

0 commit comments

Comments
 (0)