Add a Causes array to status details for validation errors

Uses the same constant values as api/errors for each nested
reason.
This commit is contained in:
Clayton Coleman
2014-08-19 22:58:24 -04:00
parent 60126bfe64
commit d326ba2976
4 changed files with 150 additions and 4 deletions

View File

@@ -21,6 +21,7 @@ import (
"net/http"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
)
@@ -76,6 +77,21 @@ func NewConflictErr(kind, name string, err error) error {
}}
}
// NewInvalidError returns an error indicating the item is invalid and cannot be processed.
func NewInvalidError(kind, name string, errs errors.ErrorList) error {
return &apiServerError{api.Status{
Status: api.StatusFailure,
Code: 422, // RFC 4918
Reason: api.ReasonTypeInvalid,
Details: &api.StatusDetails{
Kind: kind,
ID: name,
// TODO: causes
},
Message: fmt.Sprintf("%s %q is invalid: %s", kind, name, errs.ToError()),
}}
}
// IsNotFound returns true if the specified error was created by NewNotFoundErr
func IsNotFound(err error) bool {
return reasonForError(err) == api.ReasonTypeNotFound
@@ -91,6 +107,11 @@ func IsConflict(err error) bool {
return reasonForError(err) == api.ReasonTypeConflict
}
// IsInvalid determines if the err is an error which indicates the provided resource is not valid
func IsInvalid(err error) bool {
return reasonForError(err) == api.ReasonTypeInvalid
}
func reasonForError(err error) api.ReasonType {
switch t := err.(type) {
case *apiServerError:
@@ -110,7 +131,7 @@ func errToAPIStatus(err error) *api.Status {
default:
status := http.StatusInternalServerError
switch {
//TODO: replace me with NewUpdateConflictErr
//TODO: replace me with NewConflictErr
case tools.IsEtcdTestFailed(err):
status = http.StatusConflict
}

View File

@@ -35,11 +35,31 @@ func TestErrorNew(t *testing.T) {
if IsNotFound(err) {
t.Errorf(fmt.Sprintf("expected to not be %s", api.ReasonTypeNotFound))
}
if IsInvalid(err) {
t.Errorf("expected to not be invalid")
}
if !IsConflict(NewConflictErr("test", "2", errors.New("message"))) {
t.Errorf("expected to be confict")
t.Errorf("expected to be conflict")
}
if !IsNotFound(NewNotFoundErr("test", "3")) {
t.Errorf("expected to be not found")
}
if !IsInvalid(NewInvalidError("test", "2", nil)) {
t.Errorf("expected to be invalid")
}
}
func Test_errToAPIStatus(t *testing.T) {
err := &apiServerError{}
status := errToAPIStatus(err)
if status.Reason != api.ReasonTypeUnknown || status.Status != api.StatusFailure {
t.Errorf("unexpected status object: %#v", status)
}
}
func Test_reasonForError(t *testing.T) {
if e, a := api.ReasonTypeUnknown, reasonForError(nil); e != a {
t.Errorf("unexpected reason type: %#v", a)
}
}