From a6d7c80be3fbfcd2bdf6f4216617de0cf552a0e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=ADghearn=C3=A1n=20Carroll?= Date: Thu, 14 Oct 2021 10:48:02 +0100 Subject: [PATCH] Fix: Handle P4 errors on /pay (#62) * better handling of p4 errors on pay * fixed linter --- data/http/p4.go | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/data/http/p4.go b/data/http/p4.go index 5937ea23..0a8c13e5 100644 --- a/data/http/p4.go +++ b/data/http/p4.go @@ -4,10 +4,11 @@ import ( "bytes" "context" "encoding/json" - "fmt" + "errors" "net/http" "github.com/libsv/payd" + "github.com/theflyingcodr/lathos/errs" ) type p4 struct { @@ -25,20 +26,20 @@ func (p *p4) PaymentRequest(ctx context.Context, args payd.PayRequest) (*payd.Pa if err != nil { return nil, err } - res, err := p.c.Do(req) + resp, err := p.c.Do(req) if err != nil { return nil, err } defer func() { - _ = res.Body.Close() + _ = resp.Body.Close() }() - if res.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unexpected status code %d", res.StatusCode) + if resp.StatusCode != http.StatusOK { + return nil, p.handleErr(resp) } var payRec payd.PaymentRequestResponse - if err = json.NewDecoder(res.Body).Decode(&payRec); err != nil { + if err = json.NewDecoder(resp.Body).Decode(&payRec); err != nil { return nil, err } @@ -66,7 +67,7 @@ func (p *p4) PaymentSend(ctx context.Context, args payd.PayRequest, req payd.Pay }() if resp.StatusCode != http.StatusCreated { - return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) + return nil, p.handleErr(resp) } var ack payd.PaymentACK @@ -76,3 +77,31 @@ func (p *p4) PaymentSend(ctx context.Context, args payd.PayRequest, req payd.Pay return &ack, nil } + +func (p *p4) handleErr(resp *http.Response) error { + errResp := &struct { + ID string `json:"id"` + Code string `json:"code"` + Title string `json:"title"` + Message string `json:"message"` + }{} + + if err := json.NewDecoder(resp.Body).Decode(&errResp); err != nil { + return err + } + + switch resp.StatusCode { + case http.StatusUnauthorized: + return errs.NewErrNotAuthenticated(errResp.Code, errResp.Message) + case http.StatusForbidden: + return errs.NewErrNotAuthorised(errResp.Code, errResp.Message) + case http.StatusNotFound: + return errs.NewErrNotFound(errResp.Code, errResp.Message) + case http.StatusConflict: + return errs.NewErrDuplicate(errResp.Code, errResp.Message) + case http.StatusUnprocessableEntity: + return errs.NewErrUnprocessable(errResp.Code, errResp.Message) + } + + return errs.NewErrInternal(errors.New(errResp.Message), nil) +}