From 2d48f3a029611d79d664238895ec84a900d2470e Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Thu, 8 Jun 2017 14:28:48 -0700 Subject: [PATCH] client: send error events if update check or ping fails Does not report errors when sending events since that would be cyclic. --- omaha/client/client.go | 20 +++++++++++++++++--- omaha/client/error.go | 36 +++++++++++++++++++++++++++++++++--- omaha/client/http.go | 9 ++++----- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/omaha/client/client.go b/omaha/client/client.go index 8e287e3..61c25cd 100644 --- a/omaha/client/client.go +++ b/omaha/client/client.go @@ -209,11 +209,16 @@ func (ac *AppClient) UpdateCheck() (*omaha.UpdateResponse, error) { ac.sentPing = true appResp, err := ac.doReq(ac.apiEndpoint, req) - if err != nil { + if err, ok := err.(ErrorEvent); ok { + ac.Event(err.ErrorEvent()) + return nil, err + } else if err != nil { + ac.Event(NewErrorEvent(ExitCodeOmahaRequestError)) return nil, err } if appResp.Ping == nil { + ac.Event(NewErrorEvent(ExitCodeOmahaResponseInvalid)) return nil, fmt.Errorf("omaha: ping status missing from response") } @@ -222,6 +227,7 @@ func (ac *AppClient) UpdateCheck() (*omaha.UpdateResponse, error) { } if appResp.UpdateCheck == nil { + ac.Event(NewErrorEvent(ExitCodeOmahaResponseInvalid)) return nil, fmt.Errorf("omaha: update check missing from response") } @@ -240,11 +246,16 @@ func (ac *AppClient) Ping() error { ac.sentPing = true appResp, err := ac.doReq(ac.apiEndpoint, req) - if err != nil { + if err, ok := err.(ErrorEvent); ok { + ac.Event(err.ErrorEvent()) + return err + } else if err != nil { + ac.Event(NewErrorEvent(ExitCodeOmahaRequestError)) return err } if appResp.Ping == nil { + ac.Event(NewErrorEvent(ExitCodeOmahaResponseInvalid)) return fmt.Errorf("omaha: ping status missing from response") } @@ -325,7 +336,10 @@ func (ac *AppClient) doReq(url string, req *omaha.Request) (*omaha.AppResponse, appResp := resp.GetApp(appID) if appResp == nil { - return nil, fmt.Errorf("omaha: app %s missing from response", appID) + return nil, &omahaError{ + Err: fmt.Errorf("app %s missing from response", appID), + Code: ExitCodeOmahaResponseInvalid, + } } if appResp.Status != omaha.AppOK { diff --git a/omaha/client/error.go b/omaha/client/error.go index 9e1a80e..cf221a2 100644 --- a/omaha/client/error.go +++ b/omaha/client/error.go @@ -21,11 +21,19 @@ import ( "net" "net/http" "time" + + "github.com/coreos/go-omaha/omaha" ) var ( - bodySizeError = errors.New("http response exceeded 1MB") - bodyEmptyError = errors.New("http response was empty") + bodySizeError = &omahaError{ + Err: errors.New("http response exceeded 1MB"), + Code: ExitCodeOmahaResponseInvalid, + } + bodyEmptyError = &omahaError{ + Err: errors.New("http response was empty"), + Code: ExitCodeOmahaRequestEmptyResponseError, + } // default parameters for expNetBackoff backoffStart = time.Second @@ -60,7 +68,21 @@ func isUnexpectedEOF(err error) bool { return err == io.ErrUnexpectedEOF } -// httpError implements error and net.Error for http responses. +// omahaError implements error and ErrorEvent for omaha requests/responses. +type omahaError struct { + Err error + Code ExitCode +} + +func (oe *omahaError) Error() string { + return "omaha: request failed: " + oe.Err.Error() +} + +func (oe *omahaError) ErrorEvent() *omaha.EventRequest { + return NewErrorEvent(oe.Code) +} + +// httpError implements error, net.Error, and ErrorEvent for http responses. type httpError struct { *http.Response } @@ -69,6 +91,14 @@ func (he *httpError) Error() string { return "http error: " + he.Status } +func (he *httpError) ErrorEvent() *omaha.EventRequest { + code := ExitCodeOmahaRequestError + if he.StatusCode > 0 && he.StatusCode < 1000 { + code = ExitCodeOmahaRequestHTTPResponseBase + ExitCode(he.StatusCode) + } + return NewErrorEvent(code) +} + func (he *httpError) Timeout() bool { switch he.StatusCode { case http.StatusRequestTimeout: // 408 diff --git a/omaha/client/http.go b/omaha/client/http.go index 13e4a7b..9a634b7 100644 --- a/omaha/client/http.go +++ b/omaha/client/http.go @@ -45,7 +45,7 @@ func newHTTPClient() *httpClient { func (hc *httpClient) doPost(url string, reqBody []byte) (*omaha.Response, error) { resp, err := hc.Post(url, "text/xml; charset=utf-8", bytes.NewReader(reqBody)) if err != nil { - return nil, err + return nil, &omahaError{err, ExitCodeOmahaRequestError} } defer resp.Body.Close() @@ -59,6 +59,8 @@ func (hc *httpClient) doPost(url string, reqBody []byte) (*omaha.Response, error err = bodySizeError } else if err == io.EOF { err = bodyEmptyError + } else if err != nil { + err = &omahaError{err, ExitCodeOmahaRequestXMLParseError} } // Prefer reporting HTTP errors over XML parsing errors. @@ -81,9 +83,6 @@ func (hc *httpClient) Omaha(url string, req *omaha.Request) (resp *omaha.Respons resp, err = hc.doPost(url, buf.Bytes()) return err }) - if err != nil { - return nil, fmt.Errorf("omaha: request failed: %v", err) - } - return resp, nil + return resp, err }