Skip to content

Commit 1e65162

Browse files
committed
properly transform decoder error into status error
1 parent b359b6b commit 1e65162

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

staging/src/k8s.io/apiserver/pkg/endpoints/handlers/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ go_test(
2121
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
2222
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
2323
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
24+
"//staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/v1:go_default_library",
2425
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
2526
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
2627
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
@@ -33,6 +34,7 @@ go_test(
3334
"//staging/src/k8s.io/apiserver/pkg/apis/example/v1:go_default_library",
3435
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
3536
"//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library",
37+
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
3638
"//vendor/github.com/evanphx/json-patch:go_default_library",
3739
"//vendor/github.com/google/gofuzz:go_default_library",
3840
"//vendor/k8s.io/utils/trace:go_default_library",

staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,11 @@ func finishRequest(timeout time.Duration, fn resultFunc) (result runtime.Object,
229229
}
230230
}
231231

232-
// transformDecodeError adds additional information when a decode fails.
232+
// transformDecodeError adds additional information into a bad-request api error when a decode fails.
233233
func transformDecodeError(typer runtime.ObjectTyper, baseErr error, into runtime.Object, gvk *schema.GroupVersionKind, body []byte) error {
234234
objGVKs, _, err := typer.ObjectKinds(into)
235235
if err != nil {
236-
return err
236+
return errors.NewBadRequest(err.Error())
237237
}
238238
objGVK := objGVKs[0]
239239
if gvk != nil && len(gvk.Kind) > 0 {

staging/src/k8s.io/apiserver/pkg/endpoints/handlers/rest_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
apierrors "k8s.io/apimachinery/pkg/api/errors"
3232
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3333
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
34+
testapigroupv1 "k8s.io/apimachinery/pkg/apis/testapigroup/v1"
3435
"k8s.io/apimachinery/pkg/runtime"
3536
"k8s.io/apimachinery/pkg/runtime/schema"
3637
"k8s.io/apimachinery/pkg/runtime/serializer"
@@ -43,6 +44,7 @@ import (
4344
examplev1 "k8s.io/apiserver/pkg/apis/example/v1"
4445
"k8s.io/apiserver/pkg/endpoints/request"
4546
"k8s.io/apiserver/pkg/registry/rest"
47+
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
4648
utiltrace "k8s.io/utils/trace"
4749
)
4850

@@ -950,3 +952,51 @@ func (f mutateObjectUpdateFunc) Handles(operation admission.Operation) bool {
950952
func (f mutateObjectUpdateFunc) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
951953
return f(a.GetObject(), a.GetOldObject())
952954
}
955+
956+
func TestTransformDecodeErrorEnsuresBadRequestError(t *testing.T) {
957+
testCases := []struct {
958+
name string
959+
typer runtime.ObjectTyper
960+
decodedGVK *schema.GroupVersionKind
961+
decodeIntoObject runtime.Object
962+
baseErr error
963+
expectedErr error
964+
}{
965+
{
966+
name: "decoding normal objects fails and returns a bad-request error",
967+
typer: clientgoscheme.Scheme,
968+
decodedGVK: &schema.GroupVersionKind{
969+
Group: testapigroupv1.GroupName,
970+
Version: "v1",
971+
Kind: "Carp",
972+
},
973+
decodeIntoObject: &testapigroupv1.Carp{}, // which client-go's scheme doesn't recognize
974+
baseErr: fmt.Errorf("plain error"),
975+
},
976+
{
977+
name: "decoding objects with unknown GVK fails and returns a bad-request error",
978+
typer: alwaysErrorTyper{},
979+
decodedGVK: nil,
980+
decodeIntoObject: &testapigroupv1.Carp{}, // which client-go's scheme doesn't recognize
981+
baseErr: nil,
982+
},
983+
}
984+
for _, testCase := range testCases {
985+
err := transformDecodeError(testCase.typer, testCase.baseErr, testCase.decodeIntoObject, testCase.decodedGVK, []byte(``))
986+
if apiStatus, ok := err.(apierrors.APIStatus); !ok || apiStatus.Status().Code != http.StatusBadRequest {
987+
t.Errorf("expected bad request error but got: %v", err)
988+
}
989+
}
990+
}
991+
992+
var _ runtime.ObjectTyper = alwaysErrorTyper{}
993+
994+
type alwaysErrorTyper struct{}
995+
996+
func (alwaysErrorTyper) ObjectKinds(runtime.Object) ([]schema.GroupVersionKind, bool, error) {
997+
return nil, false, fmt.Errorf("always error")
998+
}
999+
1000+
func (alwaysErrorTyper) Recognizes(gvk schema.GroupVersionKind) bool {
1001+
return false
1002+
}

0 commit comments

Comments
 (0)