mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 08:17:26 +00:00
Add a new generic error that can indicate a server response was underspecified
Allows clients to distinguish between a server that returns us an error we recognize, and errors that are generic HTTP (due to an intervening proxy)
This commit is contained in:
parent
412a836bf7
commit
1233843a1d
@ -19,6 +19,7 @@ package errors
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
@ -239,6 +240,72 @@ func NewTimeoutError(message string, retryAfterSeconds int) error {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGenericServerResponse returns a new error for server responses that are not in a recognizable form.
|
||||||
|
func NewGenericServerResponse(code int, verb, kind, name, serverMessage string, retryAfterSeconds int) error {
|
||||||
|
reason := api.StatusReasonUnknown
|
||||||
|
message := fmt.Sprintf("the server responded with the status code %d but did not return more information", code)
|
||||||
|
switch code {
|
||||||
|
case http.StatusConflict:
|
||||||
|
if verb == "POST" {
|
||||||
|
reason = api.StatusReasonAlreadyExists
|
||||||
|
} else {
|
||||||
|
reason = api.StatusReasonConflict
|
||||||
|
}
|
||||||
|
message = "the server reported a conflict"
|
||||||
|
case http.StatusNotFound:
|
||||||
|
reason = api.StatusReasonNotFound
|
||||||
|
message = "the server could not find the requested resource"
|
||||||
|
case http.StatusBadRequest:
|
||||||
|
reason = api.StatusReasonBadRequest
|
||||||
|
message = "the server rejected our request for an unknown reason"
|
||||||
|
case http.StatusUnauthorized:
|
||||||
|
reason = api.StatusReasonUnauthorized
|
||||||
|
message = "the server has asked for the client to provide credentials"
|
||||||
|
case http.StatusForbidden:
|
||||||
|
reason = api.StatusReasonForbidden
|
||||||
|
message = "the server does not allow access to the requested resource"
|
||||||
|
case StatusUnprocessableEntity:
|
||||||
|
reason = api.StatusReasonInvalid
|
||||||
|
message = "the server rejected our request due to an error in our request"
|
||||||
|
case StatusServerTimeout:
|
||||||
|
reason = api.StatusReasonServerTimeout
|
||||||
|
message = "the server cannot complete the requested operation at this time, try again later"
|
||||||
|
case StatusTooManyRequests:
|
||||||
|
reason = api.StatusReasonTimeout
|
||||||
|
message = "the server has received too many requests and has asked us to try again later"
|
||||||
|
default:
|
||||||
|
if code >= 500 {
|
||||||
|
reason = api.StatusReasonInternalError
|
||||||
|
message = "an error on the server has prevented the request from succeeding"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case len(kind) > 0 && len(name) > 0:
|
||||||
|
message = fmt.Sprintf("%s (%s %s %s)", message, strings.ToLower(verb), kind, name)
|
||||||
|
case len(kind) > 0:
|
||||||
|
message = fmt.Sprintf("%s (%s %s)", message, strings.ToLower(verb), kind)
|
||||||
|
}
|
||||||
|
return &StatusError{api.Status{
|
||||||
|
Status: api.StatusFailure,
|
||||||
|
Code: code,
|
||||||
|
Reason: reason,
|
||||||
|
Details: &api.StatusDetails{
|
||||||
|
Kind: kind,
|
||||||
|
ID: name,
|
||||||
|
|
||||||
|
Causes: []api.StatusCause{
|
||||||
|
{
|
||||||
|
Type: api.CauseTypeUnexpectedServerResponse,
|
||||||
|
Message: serverMessage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
RetryAfterSeconds: retryAfterSeconds,
|
||||||
|
},
|
||||||
|
Message: message,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
// IsNotFound returns true if the specified error was created by NewNotFoundErr.
|
// IsNotFound returns true if the specified error was created by NewNotFoundErr.
|
||||||
func IsNotFound(err error) bool {
|
func IsNotFound(err error) bool {
|
||||||
return reasonForError(err) == api.StatusReasonNotFound
|
return reasonForError(err) == api.StatusReasonNotFound
|
||||||
|
@ -1431,6 +1431,10 @@ const (
|
|||||||
// CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules)
|
// CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules)
|
||||||
// values that can not be handled (e.g. an enumerated string).
|
// values that can not be handled (e.g. an enumerated string).
|
||||||
CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported"
|
CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported"
|
||||||
|
// CauseTypeUnexpectedServerResponse is used to report when the server responded to the client
|
||||||
|
// without the expected return type. The presence of this cause indicates the error may be
|
||||||
|
// due to an intervening proxy or the server software malfunctioning.
|
||||||
|
CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||||
|
Loading…
Reference in New Issue
Block a user