rpcclient: provide some exported error for disconnected WSClient
Regular Client doesn't care much about connections, because HTTP client's Do method can reuse old ones or create additional ones on the fly. So one request can fail and the next one easily succeed. WSClient is different, it works via a single connection and if it breaks, it breaks forever for this client. Callers will get some error on every request afterwards and it'd be nice for this error to be the same so that API users could detect disconnection this way too. Related to nspcc-dev/neofs-node#2325. Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
parent
8bd9a7d420
commit
fcaa24f928
2 changed files with 11 additions and 5 deletions
|
@ -454,6 +454,11 @@ const (
|
|||
// ErrNilNotificationReceiver is returned when notification receiver channel is nil.
|
||||
var ErrNilNotificationReceiver = errors.New("nil notification receiver")
|
||||
|
||||
// ErrWSConnLost is a WSClient-specific error that will be returned for any
|
||||
// requests after disconnection (including intentional ones via
|
||||
// (*WSClient).Close).
|
||||
var ErrWSConnLost = errors.New("connection lost")
|
||||
|
||||
// errConnClosedByUser is a WSClient error used iff the user calls (*WSClient).Close method by himself.
|
||||
var errConnClosedByUser = errors.New("connection closed by user")
|
||||
|
||||
|
@ -735,22 +740,22 @@ func (c *WSClient) makeWsRequest(r *neorpc.Request) (*neorpc.Response, error) {
|
|||
select {
|
||||
case <-c.done:
|
||||
c.respLock.Unlock()
|
||||
return nil, errors.New("connection lost before registering response channel")
|
||||
return nil, fmt.Errorf("%w: before registering response channel", ErrWSConnLost)
|
||||
default:
|
||||
c.respChannels[r.ID] = ch
|
||||
c.respLock.Unlock()
|
||||
}
|
||||
select {
|
||||
case <-c.done:
|
||||
return nil, errors.New("connection lost before sending the request")
|
||||
return nil, fmt.Errorf("%w: before sending the request", ErrWSConnLost)
|
||||
case c.requests <- r:
|
||||
}
|
||||
select {
|
||||
case <-c.done:
|
||||
return nil, errors.New("connection lost while waiting for the response")
|
||||
return nil, fmt.Errorf("%w: while waiting for the response", ErrWSConnLost)
|
||||
case resp, ok := <-ch:
|
||||
if !ok {
|
||||
return nil, errors.New("connection lost while waiting for the response")
|
||||
return nil, fmt.Errorf("%w: while waiting for the response", ErrWSConnLost)
|
||||
}
|
||||
c.unregisterRespChannel(r.ID)
|
||||
return resp, nil
|
||||
|
|
|
@ -3,6 +3,7 @@ package rpcclient
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
@ -752,7 +753,7 @@ func TestWS_RequestAfterClose(t *testing.T) {
|
|||
_, err = c.GetBlockCount()
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "connection lost before registering response channel"))
|
||||
require.True(t, errors.Is(err, ErrWSConnLost))
|
||||
}
|
||||
|
||||
func TestWSClient_ConnClosedError(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue