From 12b9ad1caa1ae863edd8234c9f6bb5a8262e236a Mon Sep 17 00:00:00 2001 From: Jeff Ortel Date: Sat, 15 Jul 2023 06:37:08 -0700 Subject: [PATCH] :bug: Better reporting of error responses. Signed-off-by: Jeff Ortel --- binding/client.go | 34 ++++++++++++------------- binding/error.go | 63 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 68 insertions(+), 29 deletions(-) diff --git a/binding/client.go b/binding/client.go index 6b51dcb48..959e36b01 100644 --- a/binding/client.go +++ b/binding/client.go @@ -21,7 +21,7 @@ import ( pathlib "path" "path/filepath" "strings" - "time" + "time" ) const ( @@ -140,9 +140,9 @@ func (r *Client) Get(path string, object interface{}, params ...Param) (err erro return } case http.StatusNotFound: - err = &NotFound{Path: path} + err = (&NotFound{}).With(reply) default: - err = liberr.New(http.StatusText(status)) + err = (&RestError{}).With(reply) } return @@ -188,9 +188,9 @@ func (r *Client) Post(path string, object interface{}) (err error) { } case http.StatusNoContent: case http.StatusConflict: - err = &Conflict{Path: path} + err = (&Conflict{}).With(reply) default: - err = liberr.New(http.StatusText(status)) + err = (&RestError{}).With(reply) } return } @@ -242,9 +242,9 @@ func (r *Client) Put(path string, object interface{}, params ...Param) (err erro return } case http.StatusNotFound: - err = &NotFound{Path: path} + err = (&NotFound{}).With(reply) default: - err = liberr.New(http.StatusText(status)) + err = (&RestError{}).With(reply) } return @@ -281,9 +281,9 @@ func (r *Client) Delete(path string, params ...Param) (err error) { case http.StatusOK, http.StatusNoContent: case http.StatusNotFound: - err = &NotFound{Path: path} + err = (&NotFound{}).With(reply) default: - err = liberr.New(http.StatusText(status)) + err = (&RestError{}).With(reply) } return @@ -320,9 +320,9 @@ func (r *Client) BucketGet(source, destination string) (err error) { err = r.getFile(reply.Body, source, destination) } case http.StatusNotFound: - err = &NotFound{Path: source} + err = (&NotFound{}).With(reply) default: - err = liberr.New(http.StatusText(status)) + err = (&RestError{}).With(reply) } return } @@ -383,9 +383,9 @@ func (r *Client) BucketPut(source, destination string) (err error) { http.StatusCreated, http.StatusAccepted: case http.StatusNotFound: - err = &NotFound{Path: destination} + err = (&NotFound{}).With(reply) default: - err = liberr.New(http.StatusText(status)) + err = (&RestError{}).With(reply) } return } @@ -416,9 +416,9 @@ func (r *Client) FileGet(path, destination string) (err error) { case http.StatusOK: err = r.getFile(reply.Body, "", destination) case http.StatusNotFound: - err = &NotFound{Path: path} + err = (&NotFound{}).With(reply) default: - err = liberr.New(http.StatusText(status)) + err = (&RestError{}).With(reply) } return } @@ -530,9 +530,9 @@ func (r *Client) FileSend(path, method string, fields []Field, object interface{ return } case http.StatusConflict: - err = &Conflict{Path: path} + err = (&Conflict{}).With(reply) default: - err = liberr.New(http.StatusText(status)) + err = (&RestError{}).With(reply) } return } diff --git a/binding/error.go b/binding/error.go index 0a097431a..7b48c2c7c 100644 --- a/binding/error.go +++ b/binding/error.go @@ -1,7 +1,10 @@ package binding import ( - "fmt" + "io" + "net/http" + "strconv" + "strings" ) // @@ -24,14 +27,55 @@ func (e *SoftError) Soft() *SoftError { } // -// Conflict reports 409 error. -type Conflict struct { +// RestError reports REST errors. +type RestError struct { SoftError - Path string + Method string + Path string + Status int + Body string +} + +func (e *RestError) Is(err error) (matched bool) { + _, matched = err.(*RestError) + return } -func (e Conflict) Error() string { - return fmt.Sprintf("POST: path:%s (conflict)", e.Path) +func (e *RestError) Error() (s string) { + s = e.Reason + return +} + +func (e *RestError) With(r *http.Response) *RestError { + e.Method = r.Request.Method + e.Path = r.Request.URL.Path + e.Status = r.StatusCode + if r.Body != nil { + body, err := io.ReadAll(r.Body) + if err == nil { + e.Body = string(body) + } + } + s := strings.ToUpper(e.Method) + s += " " + s += e.Path + s += " failed: " + s += strconv.Itoa(e.Status) + s += "(" + s += http.StatusText(e.Status) + s += ")" + if e.Body != "" { + s += " body: " + s += e.Body + } + e.Reason = s + return e +} + +// +// Conflict reports 409 error. +type Conflict struct { + RestError } func (e *Conflict) Is(err error) (matched bool) { @@ -42,12 +86,7 @@ func (e *Conflict) Is(err error) (matched bool) { // // NotFound reports 404 error. type NotFound struct { - SoftError - Path string -} - -func (e NotFound) Error() string { - return fmt.Sprintf("HTTP path:%s (not-found)", e.Path) + RestError } func (e *NotFound) Is(err error) (matched bool) {