From f9132dc57288ddf5deeb132b9f6ee7048f3810cb Mon Sep 17 00:00:00 2001 From: nikhiljindal Date: Wed, 15 Apr 2015 16:33:35 -0700 Subject: [PATCH] Registering serviceErrorHandler with go-restful --- pkg/api/errors/errors.go | 21 +++++++++++++-------- pkg/apiserver/apiserver.go | 12 ++++++++++++ pkg/client/request.go | 2 +- pkg/master/master.go | 1 + 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/pkg/api/errors/errors.go b/pkg/api/errors/errors.go index 9f56d658180..c000ebcf0a3 100644 --- a/pkg/api/errors/errors.go +++ b/pkg/api/errors/errors.go @@ -250,7 +250,7 @@ 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 { +func NewGenericServerResponse(code int, verb, kind, name, serverMessage string, retryAfterSeconds int, isUnexpectedResponse bool) error { reason := api.StatusReasonUnknown message := fmt.Sprintf("the server responded with the status code %d but did not return more information", code) switch code { @@ -297,6 +297,17 @@ func NewGenericServerResponse(code int, verb, kind, name, serverMessage string, case len(kind) > 0: message = fmt.Sprintf("%s (%s %s)", message, strings.ToLower(verb), kind) } + var causes []api.StatusCause + if isUnexpectedResponse { + causes = []api.StatusCause{ + { + Type: api.CauseTypeUnexpectedServerResponse, + Message: serverMessage, + }, + } + } else { + causes = nil + } return &StatusError{api.Status{ Status: api.StatusFailure, Code: code, @@ -305,13 +316,7 @@ func NewGenericServerResponse(code int, verb, kind, name, serverMessage string, Kind: kind, ID: name, - Causes: []api.StatusCause{ - { - Type: api.CauseTypeUnexpectedServerResponse, - Message: serverMessage, - }, - }, - + Causes: causes, RetryAfterSeconds: retryAfterSeconds, }, Message: message, diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index bcfc1551cfd..e18e193c8e7 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -30,6 +30,8 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/admission" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + apierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/healthz" @@ -168,6 +170,15 @@ func InstallLogsSupport(mux Mux) { mux.Handle("/logs/", http.StripPrefix("/logs/", http.FileServer(http.Dir("/var/log/")))) } +func InstallServiceErrorHandler(container *restful.Container) { + container.ServiceErrorHandler(serviceErrorHandler) +} + +func serviceErrorHandler(serviceErr restful.ServiceError, response *restful.Response) { + // TODO: Update go-restful to return the request as well, so that we can use the appropriate codec rather than using the latest one. + errorJSON(apierrors.NewGenericServerResponse(serviceErr.Code, "", "", "", "", 0, false), latest.Codec, response.ResponseWriter) +} + // Adds a service to return the supported api versions. func AddApiWebService(container *restful.Container, apiPrefix string, versions []string) { // TODO: InstallREST should register each version automatically @@ -246,6 +257,7 @@ func writeJSON(statusCode int, codec runtime.Codec, object runtime.Object, w htt return } w.Header().Set("Content-Type", "application/json") + glog.Infof("Writting status code: %d", statusCode) w.WriteHeader(statusCode) w.Write(formatted.Bytes()) } diff --git a/pkg/client/request.go b/pkg/client/request.go index d87b44dab21..df6419df0c4 100644 --- a/pkg/client/request.go +++ b/pkg/client/request.go @@ -785,7 +785,7 @@ func (r *Request) transformUnstructuredResponseError(resp *http.Response, req *h message = strings.TrimSpace(string(body)) } retryAfter, _ := retryAfterSeconds(resp) - return errors.NewGenericServerResponse(resp.StatusCode, req.Method, r.resource, r.resourceName, message, retryAfter) + return errors.NewGenericServerResponse(resp.StatusCode, req.Method, r.resource, r.resourceName, message, retryAfter, true) } // isTextResponse returns true if the response appears to be a textual media type. diff --git a/pkg/master/master.go b/pkg/master/master.go index 8d750dfbed6..ca7c987df4f 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -431,6 +431,7 @@ func (m *Master) init(c *Config) { apiserver.InstallSupport(m.muxHelper, m.rootWebService) apiserver.AddApiWebService(m.handlerContainer, c.APIPrefix, apiVersions) + apiserver.InstallServiceErrorHandler(m.handlerContainer) // Register root handler. // We do not register this using restful Webservice since we do not want to surface this in api docs.