Don't hold up the entire event queue for a single bad event. Also, don't retry forever.

This commit is contained in:
Daniel Smith
2014-11-20 16:01:42 -08:00
parent c6158b8aa9
commit 4437f03dbf
5 changed files with 183 additions and 26 deletions

View File

@@ -24,34 +24,46 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
// statusError is an error intended for consumption by a REST API server.
type statusError struct {
status api.Status
// StatusError is an error intended for consumption by a REST API server; it can also be
// reconstructed by clients from a REST response. Public to allow easy type switches.
type StatusError struct {
ErrStatus api.Status
}
// Error implements the Error interface.
func (e *statusError) Error() string {
return e.status.Message
func (e *StatusError) Error() string {
return e.ErrStatus.Message
}
// Status converts this error into an api.Status object.
func (e *statusError) Status() api.Status {
return e.status
// Status allows access to e's status without having to know the detailed workings
// of StatusError. Used by pkg/apiserver.
func (e *StatusError) Status() api.Status {
return e.ErrStatus
}
// FromObject generates an statusError from an api.Status, if that is the type of obj; otherwise,
// returns an error created by fmt.Errorf.
// UnexpectedObjectError can be returned by FromObject if it's passed a non-status object.
type UnexpectedObjectError struct {
Object runtime.Object
}
// Error returns an error message describing 'u'.
func (u *UnexpectedObjectError) Error() string {
return fmt.Sprintf("unexpected object: %v", u.Object)
}
// FromObject generates an StatusError from an api.Status, if that is the type of obj; otherwise,
// returns an UnexpecteObjectError.
func FromObject(obj runtime.Object) error {
switch t := obj.(type) {
case *api.Status:
return &statusError{*t}
return &StatusError{*t}
}
return fmt.Errorf("unexpected object: %v", obj)
return &UnexpectedObjectError{obj}
}
// NewNotFound returns a new error which indicates that the resource of the kind and the name was not found.
func NewNotFound(kind, name string) error {
return &statusError{api.Status{
return &StatusError{api.Status{
Status: api.StatusFailure,
Code: http.StatusNotFound,
Reason: api.StatusReasonNotFound,
@@ -65,7 +77,7 @@ func NewNotFound(kind, name string) error {
// NewAlreadyExists returns an error indicating the item requested exists by that identifier.
func NewAlreadyExists(kind, name string) error {
return &statusError{api.Status{
return &StatusError{api.Status{
Status: api.StatusFailure,
Code: http.StatusConflict,
Reason: api.StatusReasonAlreadyExists,
@@ -79,7 +91,7 @@ func NewAlreadyExists(kind, name string) error {
// NewConflict returns an error indicating the item can't be updated as provided.
func NewConflict(kind, name string, err error) error {
return &statusError{api.Status{
return &StatusError{api.Status{
Status: api.StatusFailure,
Code: http.StatusConflict,
Reason: api.StatusReasonConflict,
@@ -103,7 +115,7 @@ func NewInvalid(kind, name string, errs ValidationErrorList) error {
})
}
}
return &statusError{api.Status{
return &StatusError{api.Status{
Status: api.StatusFailure,
Code: 422, // RFC 4918: StatusUnprocessableEntity
Reason: api.StatusReasonInvalid,
@@ -118,7 +130,7 @@ func NewInvalid(kind, name string, errs ValidationErrorList) error {
// NewBadRequest creates an error that indicates that the request is invalid and can not be processed.
func NewBadRequest(reason string) error {
return &statusError{
return &StatusError{
api.Status{
Status: api.StatusFailure,
Code: http.StatusBadRequest,
@@ -134,7 +146,7 @@ func NewBadRequest(reason string) error {
// NewInternalError returns an error indicating the item is invalid and cannot be processed.
func NewInternalError(err error) error {
return &statusError{api.Status{
return &StatusError{api.Status{
Status: api.StatusFailure,
Code: http.StatusInternalServerError,
Reason: api.StatusReasonInternalError,
@@ -172,8 +184,8 @@ func IsBadRequest(err error) bool {
func reasonForError(err error) api.StatusReason {
switch t := err.(type) {
case *statusError:
return t.status.Reason
case *StatusError:
return t.ErrStatus.Reason
}
return api.StatusReasonUnknown
}

View File

@@ -117,7 +117,7 @@ func TestNewInvalid(t *testing.T) {
vErr, expected := testCase.Err, testCase.Details
expected.Causes[0].Message = vErr.Error()
err := NewInvalid("kind", "name", ValidationErrorList{vErr})
status := err.(*statusError).Status()
status := err.(*StatusError).ErrStatus
if status.Code != 422 || status.Reason != api.StatusReasonInvalid {
t.Errorf("%d: unexpected status: %#v", i, status)
}