Skip to content

Commit

Permalink
Fix: Handle P4 errors on /pay (#62)
Browse files Browse the repository at this point in the history
* better handling of p4 errors on pay

* fixed linter
  • Loading branch information
tigh-latte authored Oct 14, 2021
1 parent 4223970 commit a6d7c80
Showing 1 changed file with 36 additions and 7 deletions.
43 changes: 36 additions & 7 deletions data/http/p4.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}

Expand Down Expand Up @@ -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
Expand All @@ -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)
}

0 comments on commit a6d7c80

Please sign in to comment.