Skip to content

Commit

Permalink
Use error constants whenever possible
Browse files Browse the repository at this point in the history
Signed-off-by: Yilun <[email protected]>
  • Loading branch information
yilunzhang committed Apr 10, 2020
1 parent a095f4a commit ff001fc
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 61 deletions.
24 changes: 13 additions & 11 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"log"
"net/url"
"strings"
Expand Down Expand Up @@ -193,14 +192,14 @@ func (c *Client) getOrComputeSharedKey(remotePublicKey []byte) (*[sharedKeySize]
}

if len(remotePublicKey) != ed25519.PublicKeySize {
return nil, fmt.Errorf("public key length is %d, expecting %d", len(remotePublicKey), ed25519.PublicKeySize)
return nil, ErrInvalidPubkeySize
}

var pk [ed25519.PublicKeySize]byte
copy(pk[:], remotePublicKey)
curve25519PublicKey, ok := ed25519.PublicKeyToCurve25519PublicKey(&pk)
if !ok {
return nil, fmt.Errorf("converting public key %x to curve25519 public key failed", remotePublicKey)
return nil, ErrInvalidPubkey
}

sharedKey = new([sharedKeySize]byte)
Expand Down Expand Up @@ -373,7 +372,10 @@ func (c *Client) handleMessage(msgType int, data []byte) error {
} else if action == setClientAction {
c.Close()
}
return errors.New(common.ErrMessage[errCode])
return errorWithCode{
err: errors.New(common.ErrMessage[errCode]),
code: int32(errCode),
}
}
switch action {
case setClientAction:
Expand Down Expand Up @@ -623,7 +625,7 @@ func (c *Client) connect(maxRetries int) error {
return nil
}

return errors.New("max retry reached, connect failed")
return ErrConnectFailed
}

func (c *Client) reconnect() {
Expand Down Expand Up @@ -742,7 +744,7 @@ func (c *Client) SendText(dests *StringArray, data string, config *MessageConfig

func (c *Client) processDest(dest string) (string, error) {
if len(dest) == 0 {
return "", errors.New("destination is empty")
return "", ErrNoDestination
}
addr := strings.Split(dest, ".")
if len(addr[len(addr)-1]) < 2*ed25519.PublicKeySize {
Expand All @@ -751,7 +753,7 @@ func (c *Client) processDest(dest string) (string, error) {
return "", err
}
if len(reg.Registrant) == 0 {
return "", fmt.Errorf("%s is neither a valid public key nor a registered nam", addr[len(addr)-1])
return "", ErrInvalidPubkeyOrName
}
addr[len(addr)-1] = reg.Registrant
}
Expand All @@ -769,7 +771,7 @@ func (c *Client) processDests(dests []string) ([]string, error) {
processedDests = append(processedDests, processedDest)
}
if len(processedDests) == 0 {
return nil, errors.New("all destinations are invalid")
return nil, ErrInvalidDestination
}
return processedDests, nil
}
Expand Down Expand Up @@ -921,7 +923,7 @@ func (c *Client) sendTimeout(dests []string, payload *payloads.Payload, encrypte
for i := range plds {
size = len(plds[i]) + len(dests[i]) + ed25519.SignatureSize
if size > maxClientMessageSize {
return fmt.Errorf("encoded message is greater than %v bytes", maxClientMessageSize)
return ErrMessageOversize
}
if totalSize+size > maxClientMessageSize {
outboundMsg, err := c.newOutboundMessage(destList, pldList, encrypted, maxHoldingSeconds)
Expand All @@ -943,7 +945,7 @@ func (c *Client) sendTimeout(dests []string, payload *payloads.Payload, encrypte
size += len(dests[i]) + ed25519.SignatureSize
}
if size > maxClientMessageSize {
return fmt.Errorf("encoded message is greater than %v bytes", maxClientMessageSize)
return ErrMessageOversize
}
destList = dests
pldList = plds
Expand Down Expand Up @@ -1052,7 +1054,7 @@ func (c *Client) SetWriteDeadline(deadline time.Time) error {
c.lock.Lock()
defer c.lock.Unlock()
if c.conn == nil {
return errors.New("nil websocket connection")
return ErrNilWebsocketConn
}
return c.conn.SetWriteDeadline(deadline)
}
Expand Down
32 changes: 29 additions & 3 deletions error.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package nkn

import (
"errors"
"fmt"

ncp "github.com/nknorg/ncp-go"
"github.com/nknorg/nkn/vault"
)

// ErrorWithCode is an error interface that implements error and Code()
Expand All @@ -23,8 +27,30 @@ func (e errorWithCode) Code() int32 {
return e.code
}

// Error definitions.
var (
ErrClosed = ncp.NewGenericError("use of closed network connection", true, true) // The error message is meant to be identical to error returned by net package.
ErrKeyNotInMap = ncp.NewGenericError("key not in map", false, false) // for gomobile
ErrInvalidPayloadType = ncp.NewGenericError("invalid payload type", false, false)
ErrClosed = ncp.NewGenericError("use of closed network connection", true, true) // The error message is meant to be identical to error returned by net package.
ErrKeyNotInMap = errors.New("key not in map") // for gomobile
ErrInvalidPayloadType = errors.New("invalid payload type")
ErrConnectFailed = errors.New("connect failed")
ErrNoDestination = errors.New("no destination")
ErrInvalidDestination = errors.New("invalid destination")
ErrInvalidPubkeyOrName = errors.New("invalid public key or name")
ErrInvalidPubkeySize = errors.New("invalid public key size")
ErrInvalidPubkey = errors.New("invalid public key")
ErrMessageOversize = fmt.Errorf("encoded message is greater than %v bytes", maxClientMessageSize)
ErrNilWebsocketConn = errors.New("nil websocket connection")
ErrDecryptFailed = errors.New("decrypt message failed")
ErrAddrNotAllowed = errors.New("address not allowed")
ErrCreateClientFailed = errors.New("failed to create client")
ErrNilClient = errors.New("client is nil")
ErrNotNanoPay = errors.New("not nano pay transaction")
ErrWrongRecipient = errors.New("wrong nano pay recipient")
ErrNanoPayClosed = errors.New("use of closed nano pay claimer")
ErrInsufficientBalance = errors.New("insufficient balance")
ErrInvalidAmount = errors.New("invalid amount")
ErrExpiredNanoPay = errors.New("nanopay expired")
ErrExpiredNanoPayTxn = errors.New("nanopay transaction expired")
ErrWrongPassword = errors.New("wrong password")
ErrInvalidWalletVersion = fmt.Errorf("invalid wallet version, should be between %v and %v", vault.MinCompatibleWalletVersion, vault.MaxCompatibleWalletVersion)
)
41 changes: 20 additions & 21 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package nkn

import (
"crypto/rand"
"errors"

"github.com/gogo/protobuf/proto"
"github.com/nknorg/nkn-sdk-go/payloads"
Expand Down Expand Up @@ -64,34 +63,34 @@ func decrypt(message []byte, nonce [nonceSize]byte, sharedKey *[sharedKeySize]by
decrypted := make([]byte, len(message)-box.Overhead)
_, ok := box.OpenAfterPrecomputation(decrypted[:0], message, &nonce, sharedKey)
if !ok {
return nil, errors.New("decrypt message failed")
return nil, ErrDecryptFailed
}

return decrypted, nil
}

func newBinaryPayload(data, messageId, replyToId []byte, noReply bool) (*payloads.Payload, error) {
if len(messageId) == 0 && len(replyToId) == 0 {
func newBinaryPayload(data, messageID, replyToID []byte, noReply bool) (*payloads.Payload, error) {
if len(messageID) == 0 && len(replyToID) == 0 {
var err error
messageId, err = RandomBytes(MessageIDSize)
messageID, err = RandomBytes(MessageIDSize)
if err != nil {
return nil, err
}
}

return &payloads.Payload{
Type: payloads.BINARY,
MessageId: messageId,
MessageId: messageID,
Data: data,
ReplyToId: replyToId,
ReplyToId: replyToID,
NoReply: noReply,
}, nil
}

func newTextPayload(text string, messageId, replyToId []byte, noReply bool) (*payloads.Payload, error) {
if len(messageId) == 0 && len(replyToId) == 0 {
func newTextPayload(text string, messageID, replyToID []byte, noReply bool) (*payloads.Payload, error) {
if len(messageID) == 0 && len(replyToID) == 0 {
var err error
messageId, err = RandomBytes(MessageIDSize)
messageID, err = RandomBytes(MessageIDSize)
if err != nil {
return nil, err
}
Expand All @@ -104,39 +103,39 @@ func newTextPayload(text string, messageId, replyToId []byte, noReply bool) (*pa

return &payloads.Payload{
Type: payloads.TEXT,
MessageId: messageId,
MessageId: messageID,
Data: data,
ReplyToId: replyToId,
ReplyToId: replyToID,
NoReply: noReply,
}, nil
}

func newAckPayload(replyToId []byte) (*payloads.Payload, error) {
func newAckPayload(replyToID []byte) (*payloads.Payload, error) {
return &payloads.Payload{
Type: payloads.ACK,
ReplyToId: replyToId,
ReplyToId: replyToID,
}, nil
}

func newMessagePayload(data interface{}, messageId []byte, noReply bool) (*payloads.Payload, error) {
func newMessagePayload(data interface{}, messageID []byte, noReply bool) (*payloads.Payload, error) {
switch v := data.(type) {
case []byte:
return newBinaryPayload(v, messageId, nil, noReply)
return newBinaryPayload(v, messageID, nil, noReply)
case string:
return newTextPayload(v, messageId, nil, noReply)
return newTextPayload(v, messageID, nil, noReply)
default:
return nil, ErrInvalidPayloadType
}
}

func newReplyPayload(data interface{}, replyToId []byte) (*payloads.Payload, error) {
func newReplyPayload(data interface{}, replyToID []byte) (*payloads.Payload, error) {
switch v := data.(type) {
case []byte:
return newBinaryPayload(v, nil, replyToId, false)
return newBinaryPayload(v, nil, replyToID, false)
case string:
return newTextPayload(v, nil, replyToId, false)
return newTextPayload(v, nil, replyToID, false)
case nil:
return newAckPayload(replyToId)
return newAckPayload(replyToID)
default:
return nil, ErrInvalidPayloadType
}
Expand Down
26 changes: 12 additions & 14 deletions multiclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package nkn

import (
"context"
"errors"
"fmt"
"log"
"net"
"regexp"
Expand All @@ -13,6 +11,7 @@ import (
"sync"
"time"

multierror "github.com/hashicorp/go-multierror"
ncp "github.com/nknorg/ncp-go"
"github.com/nknorg/nkn-sdk-go/payloads"
"github.com/nknorg/nkn/util/address"
Expand All @@ -37,7 +36,6 @@ const (

var (
multiClientIdentifierRe = regexp.MustCompile(MultiClientIdentifierRe)
errAddrNotAllowed = errors.New("address not allowed")
)

// MultiClient sends and receives data using multiple NKN clients concurrently
Expand Down Expand Up @@ -142,7 +140,7 @@ func NewMultiClient(account *Account, baseIdentifier string, numSubClients int,
}
err := m.handleSessionMsg(addIdentifier("", i-offset), msg.Src, msg.MessageID, msg.Data)
if err != nil {
if err != ncp.ErrSessionClosed && err != errAddrNotAllowed {
if err != ncp.ErrSessionClosed && err != ErrAddrNotAllowed {
log.Println(err)
}
continue
Expand Down Expand Up @@ -192,7 +190,7 @@ func NewMultiClient(account *Account, baseIdentifier string, numSubClients int,
case <-success:
return m, nil
case <-fail:
return nil, errors.New("failed to create any client")
return nil, ErrCreateClientFailed
}
}

Expand Down Expand Up @@ -245,7 +243,7 @@ func (m *MultiClient) GetDefaultClient() *Client {
func (m *MultiClient) SendWithClient(clientID int, dests *StringArray, data interface{}, config *MessageConfig) (*OnMessage, error) {
client := m.GetClient(clientID)
if client == nil {
return nil, fmt.Errorf("client %d is not created or not ready", clientID)
return nil, ErrNilClient
}

config, err := MergeMessageConfig(m.config.MessageConfig, config)
Expand Down Expand Up @@ -285,7 +283,7 @@ func (m *MultiClient) SendTextWithClient(clientID int, dests *StringArray, data
func (m *MultiClient) sendWithClient(clientID int, dests []string, payload *payloads.Payload, encrypted bool, maxHoldingSeconds int32) error {
client := m.GetClient(clientID)
if client == nil {
return fmt.Errorf("client %d is not created or not ready", clientID)
return ErrNilClient
}
return client.send(addMultiClientPrefix(dests, clientID), payload, encrypted, maxHoldingSeconds)
}
Expand All @@ -305,7 +303,7 @@ func (m *MultiClient) Send(dests *StringArray, data interface{}, config *Message
}

var lock sync.Mutex
var errMsg []string
var errs error
var onRawReply *OnMessage
onReply := NewOnMessage(1, nil)
clients := m.GetClients()
Expand Down Expand Up @@ -333,7 +331,7 @@ func (m *MultiClient) Send(dests *StringArray, data interface{}, config *Message
sent++
} else {
lock.Lock()
errMsg = append(errMsg, err.Error())
errs = multierror.Append(errs, err)
lock.Unlock()
}
}
Expand All @@ -355,7 +353,7 @@ func (m *MultiClient) Send(dests *StringArray, data interface{}, config *Message
case <-success:
return onReply, nil
case <-fail:
return nil, errors.New(strings.Join(errMsg, "; "))
return nil, errs
}
}

Expand All @@ -373,7 +371,7 @@ func (m *MultiClient) SendText(dests *StringArray, data string, config *MessageC

func (m *MultiClient) send(dests []string, payload *payloads.Payload, encrypted bool, maxHoldingSeconds int32) error {
var lock sync.Mutex
var errMsg []string
var errs error
success := make(chan struct{}, 1)
fail := make(chan struct{}, 1)
go func() {
Expand All @@ -388,7 +386,7 @@ func (m *MultiClient) send(dests []string, payload *payloads.Payload, encrypted
sent++
} else {
lock.Lock()
errMsg = append(errMsg, err.Error())
errs = multierror.Append(errs, err)
lock.Unlock()
}
}
Expand All @@ -404,7 +402,7 @@ func (m *MultiClient) send(dests []string, payload *payloads.Payload, encrypted
case <-success:
return nil
case <-fail:
return errors.New(strings.Join(errMsg, "; "))
return errs
}
}

Expand Down Expand Up @@ -470,7 +468,7 @@ func (m *MultiClient) handleSessionMsg(localClientID, src string, sessionID, dat
if !ok {
if !m.shouldAcceptAddr(remoteAddr) {
m.sessionLock.Unlock()
return errAddrNotAllowed
return ErrAddrNotAllowed
}

session, err = m.newSession(remoteAddr, sessionID, m.config.SessionConfig)
Expand Down
Loading

0 comments on commit ff001fc

Please sign in to comment.