Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(SPV-846): refactor numeric error codes into strings #245

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions authentication.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/bitcoin-sv/spv-wallet-go-client/utils"
"github.com/bitcoin-sv/spv-wallet/models"
"github.com/bitcoin-sv/spv-wallet/models/apierrors"
"github.com/bitcoinschema/go-bitcoin/v2"
"github.com/libsv/go-bk/bec"
"github.com/libsv/go-bk/bip32"
Expand All @@ -18,7 +17,7 @@ import (
)

// SetSignature will set the signature on the header for the request
func setSignature(header *http.Header, xPriv *bip32.ExtendedKey, bodyString string) ResponseError {
func setSignature(header *http.Header, xPriv *bip32.ExtendedKey, bodyString string) error {
// Create the signature
authData, err := createSignature(xPriv, bodyString)
if err != nil {
Expand All @@ -28,7 +27,9 @@ func setSignature(header *http.Header, xPriv *bip32.ExtendedKey, bodyString stri
// Set the auth header
header.Set(models.AuthHeader, authData.XPub)

return setSignatureHeaders(header, authData)
setSignatureHeaders(header, authData)
ac4ch marked this conversation as resolved.
Show resolved Hide resolved

return nil
}

// GetSignedHex will sign all the inputs using the given xPriv key
Expand Down Expand Up @@ -134,7 +135,7 @@ func getUnlockingScript(tx *bt.Tx, inputIndex uint32, privateKey *bec.PrivateKey
func createSignature(xPriv *bip32.ExtendedKey, bodyString string) (payload *models.AuthPayload, err error) {
// No key?
if xPriv == nil {
err = apierrors.ErrMissingXPriv
err = ErrMissingXpriv
return
}

Expand Down Expand Up @@ -199,7 +200,7 @@ func getSigningMessage(xPub string, auth *models.AuthPayload) string {
return fmt.Sprintf("%s%s%s%d", xPub, auth.AuthHash, auth.AuthNonce, auth.AuthTime)
}

func setSignatureHeaders(header *http.Header, authData *models.AuthPayload) ResponseError {
func setSignatureHeaders(header *http.Header, authData *models.AuthPayload) {
// Create the auth header hash
header.Set(models.AuthHeaderHash, authData.AuthHash)

Expand All @@ -211,6 +212,4 @@ func setSignatureHeaders(header *http.Header, authData *models.AuthPayload) Resp

// Set the signature
header.Set(models.AuthSignature, authData.Signature)

return nil
}
63 changes: 24 additions & 39 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,56 @@ package walletclient

import (
"encoding/json"
"errors"
"fmt"
"io"
"github.com/bitcoin-sv/spv-wallet/models"
"net/http"
)

// ErrAdminKey admin key not set
var ErrAdminKey = errors.New("an admin key must be set to be able to create an xpub")
var ErrAdminKey = models.SPVError{Message: "an admin key must be set to be able to create an xpub", StatusCode: 401, Code: "error-unauthorized-admin-key-not-set"}

// ErrNoClientSet is when no client is set
var ErrNoClientSet = errors.New("no transport client set")
// ErrMissingXpriv is when xpriv is missing
var ErrMissingXpriv = models.SPVError{Message: "xpriv missing", StatusCode: 401, Code: "error-unauthorized-xpriv-missing"}

// ResError is a struct which contain information about error
type ResError struct {
StatusCode int
Message string
}

// ResponseError is an interface for error
type ResponseError interface {
Error() string
GetStatusCode() int
}
// ErrCouldNotFindDraftTransaction is when draft transaction is not found
var ErrCouldNotFindDraftTransaction = models.SPVError{Message: "could not find draft transaction", StatusCode: 404, Code: "error-draft-transaction-not-found"}

// WrapError wraps an error into ResponseError
func WrapError(err error) ResponseError {
// WrapError wraps an error into SPVError
func WrapError(err error) error {
if err == nil {
return nil
}

return &ResError{
return &models.SPVError{
StatusCode: http.StatusInternalServerError,
Message: err.Error(),
Code: models.UnknownErrorCode,
}
}

// WrapResponseError wraps a http response into ResponseError
func WrapResponseError(res *http.Response) ResponseError {
// WrapResponseError wraps a http response into SPVError
func WrapResponseError(res *http.Response) error {
if res == nil {
return nil
}

var errorMsg string
var resError *models.ResponseError

err := json.NewDecoder(res.Body).Decode(&errorMsg)
err := json.NewDecoder(res.Body).Decode(&resError)
if err != nil {
// if EOF, then body is empty and we return response status as error message
if !errors.Is(err, io.EOF) {
errorMsg = fmt.Sprintf("spv-wallet error message can't be decoded. Reason: %s", err.Error())
}
errorMsg = res.Status
return WrapError(err)
}

return &ResError{
return &models.SPVError{
StatusCode: res.StatusCode,
Message: errorMsg,
Code: resError.Code,
Message: resError.Message,
}
}

// Error returns the error message
func (e *ResError) Error() string {
return e.Message
}

// GetStatusCode returns the status code of error
func (e *ResError) GetStatusCode() int {
return e.StatusCode
func CreateErrorResponse(code string, message string) error {
return &models.SPVError{
StatusCode: http.StatusInternalServerError,
Code: code,
Message: message,
}
}
4 changes: 2 additions & 2 deletions examples/go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions examples/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions examples/handle_exceptions/handle_exceptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ package main

import (
"context"
"errors"
"fmt"
"os"

walletclient "github.com/bitcoin-sv/spv-wallet-go-client"
"github.com/bitcoin-sv/spv-wallet-go-client/examples"
"github.com/bitcoin-sv/spv-wallet/models"
)

func main() {
Expand All @@ -24,8 +26,12 @@ func main() {

status, err := client.AdminGetStatus(ctx)
if err != nil {
fmt.Println("Response status: ", err.GetStatusCode())
fmt.Println("Content: ", err.Error())
var extendedErr models.ExtendedError
if errors.As(err, &extendedErr) {
fmt.Printf("Extended error: [%d] '%s': %s\n", extendedErr.GetStatusCode(), extendedErr.GetCode(), extendedErr.GetMessage())
} else {
fmt.Println("Error: ", err.Error())
}

os.Exit(1)
}
Expand Down
31 changes: 29 additions & 2 deletions go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 83 additions & 0 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading