rpc: modify New* functions to return error (#4274)

The New* client functions return an error instead
of panicking when the remote address is invalid.

Fixes #3953
This commit is contained in:
Peter Mrekaj
2020-01-07 07:07:03 +01:00
committed by Anton Kaliaev
parent 7be74c73b7
commit 8f5d58f32e
19 changed files with 156 additions and 75 deletions

View File

@@ -18,7 +18,10 @@ func ExampleHTTP_simple() {
// Create our RPC client
rpcAddr := rpctest.GetConfig().RPC.ListenAddress
c := client.NewHTTP(rpcAddr, "/websocket")
c, err := client.NewHTTP(rpcAddr, "/websocket")
if err != nil {
panic(err)
}
// Create a transaction
k := []byte("name")
@@ -68,7 +71,10 @@ func ExampleHTTP_batching() {
// Create our RPC client
rpcAddr := rpctest.GetConfig().RPC.ListenAddress
c := client.NewHTTP(rpcAddr, "/websocket")
c, err := client.NewHTTP(rpcAddr, "/websocket")
if err != nil {
panic(err)
}
// Create our two transactions
k1 := []byte("firstName")

View File

@@ -87,29 +87,38 @@ var _ rpcClient = (*baseRPCClient)(nil)
// NewHTTP takes a remote endpoint in the form <protocol>://<host>:<port> and
// the websocket path (which always seems to be "/websocket")
// The function panics if the provided remote is invalid.<Paste>
func NewHTTP(remote, wsEndpoint string) *HTTP {
httpClient := rpcclient.DefaultHTTPClient(remote)
// An error is returned on invalid remote. The function panics when remote is nil.
func NewHTTP(remote, wsEndpoint string) (*HTTP, error) {
httpClient, err := rpcclient.DefaultHTTPClient(remote)
if err != nil {
return nil, err
}
return NewHTTPWithClient(remote, wsEndpoint, httpClient)
}
// NewHTTPWithClient allows for setting a custom http client. See NewHTTP
// The function panics if the provided client is nil or remote is invalid.
func NewHTTPWithClient(remote, wsEndpoint string, client *http.Client) *HTTP {
// NewHTTPWithClient allows for setting a custom http client (See NewHTTP).
// An error is returned on invalid remote. The function panics when remote is nil.
func NewHTTPWithClient(remote, wsEndpoint string, client *http.Client) (*HTTP, error) {
if client == nil {
panic("nil http.Client provided")
}
rc := rpcclient.NewJSONRPCClientWithHTTPClient(remote, client)
rc, err := rpcclient.NewJSONRPCClientWithHTTPClient(remote, client)
if err != nil {
return nil, err
}
cdc := rc.Codec()
ctypes.RegisterAmino(cdc)
rc.SetCodec(cdc)
return &HTTP{
httpClient := &HTTP{
rpc: rc,
remote: remote,
baseRPCClient: &baseRPCClient{caller: rc},
WSEvents: newWSEvents(cdc, remote, wsEndpoint),
}
return httpClient, nil
}
var _ Client = (*HTTP)(nil)
@@ -404,15 +413,18 @@ func newWSEvents(cdc *amino.Codec, remote, endpoint string) *WSEvents {
}
// OnStart implements service.Service by starting WSClient and event loop.
func (w *WSEvents) OnStart() error {
w.ws = rpcclient.NewWSClient(w.remote, w.endpoint, rpcclient.OnReconnect(func() {
func (w *WSEvents) OnStart() (err error) {
w.ws, err = rpcclient.NewWSClient(w.remote, w.endpoint, rpcclient.OnReconnect(func() {
// resubscribe immediately
w.redoSubscriptionsAfter(0 * time.Second)
}))
if err != nil {
return err
}
w.ws.SetCodec(w.cdc)
w.ws.SetLogger(w.Logger)
err := w.ws.Start()
err = w.ws.Start()
if err != nil {
return err
}

View File

@@ -29,7 +29,10 @@ import (
func getHTTPClient() *client.HTTP {
rpcAddr := rpctest.GetConfig().RPC.ListenAddress
c := client.NewHTTP(rpcAddr, "/websocket")
c, err := client.NewHTTP(rpcAddr, "/websocket")
if err != nil {
panic(err)
}
c.SetLogger(log.TestingLogger())
return c
}
@@ -48,16 +51,17 @@ func GetClients() []client.Client {
func TestNilCustomHTTPClient(t *testing.T) {
require.Panics(t, func() {
client.NewHTTPWithClient("http://example.com", "/websocket", nil)
_, _ = client.NewHTTPWithClient("http://example.com", "/websocket", nil)
})
require.Panics(t, func() {
rpcclient.NewJSONRPCClientWithHTTPClient("http://example.com", nil)
_, _ = rpcclient.NewJSONRPCClientWithHTTPClient("http://example.com", nil)
})
}
func TestCustomHTTPClient(t *testing.T) {
remote := rpctest.GetConfig().RPC.ListenAddress
c := client.NewHTTPWithClient(remote, "/websocket", http.DefaultClient)
c, err := client.NewHTTPWithClient(remote, "/websocket", http.DefaultClient)
require.Nil(t, err)
status, err := c.Status()
require.NoError(t, err)
require.NotNil(t, status)