internal/jsonrpc2_v2: consider ErrClosedPipe as a closing error
There was already handling in isClosingErr for errors from Stdin/Stdout and TCP connections. Add handling for io.Pipe closing errors. Change-Id: I8d171ab49a3fffe0fca9f0482f6b92d61b1fae1f Reviewed-on: https://go-review.googlesource.com/c/tools/+/320849 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
parent
76e263b8c9
commit
df36e4f0cb
2 changed files with 17 additions and 8 deletions
|
|
@ -133,16 +133,21 @@ func isClosingError(err error) bool {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// fully unwrap the error, so the following tests work
|
// Fully unwrap the error, so the following tests work.
|
||||||
for wrapped := err; wrapped != nil; wrapped = errors.Unwrap(err) {
|
for wrapped := err; wrapped != nil; wrapped = errors.Unwrap(err) {
|
||||||
err = wrapped
|
err = wrapped
|
||||||
}
|
}
|
||||||
|
|
||||||
// was it based on an EOF error?
|
// Was it based on an EOF error?
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Was it based on a closed pipe?
|
||||||
|
if err == io.ErrClosedPipe {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Per https://github.com/golang/go/issues/4373, this error string should not
|
// Per https://github.com/golang/go/issues/4373, this error string should not
|
||||||
// change. This is not ideal, but since the worst that could happen here is
|
// change. This is not ideal, but since the worst that could happen here is
|
||||||
// some superfluous logging, it is acceptable.
|
// some superfluous logging, it is acceptable.
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,11 @@ func TestServe(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
conn, shutdown, err := newFake(ctx, fake)
|
conn, shutdown, err := newFake(t, ctx, fake)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer shutdown(ctx)
|
defer shutdown()
|
||||||
var got msg
|
var got msg
|
||||||
if err := conn.Call(ctx, "ping", &msg{"ting"}).Await(ctx, &got); err != nil {
|
if err := conn.Call(ctx, "ping", &msg{"ting"}).Await(ctx, &got); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|
@ -115,7 +115,7 @@ func TestServe(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFake(ctx context.Context, l jsonrpc2.Listener) (*jsonrpc2.Connection, func(context.Context), error) {
|
func newFake(t *testing.T, ctx context.Context, l jsonrpc2.Listener) (*jsonrpc2.Connection, func(), error) {
|
||||||
l = jsonrpc2.NewIdleListener(100*time.Millisecond, l)
|
l = jsonrpc2.NewIdleListener(100*time.Millisecond, l)
|
||||||
server, err := jsonrpc2.Serve(ctx, l, jsonrpc2.ConnectionOptions{
|
server, err := jsonrpc2.Serve(ctx, l, jsonrpc2.ConnectionOptions{
|
||||||
Handler: fakeHandler{},
|
Handler: fakeHandler{},
|
||||||
|
|
@ -132,9 +132,13 @@ func newFake(ctx context.Context, l jsonrpc2.Listener) (*jsonrpc2.Connection, fu
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
return client, func(ctx context.Context) {
|
return client, func() {
|
||||||
l.Close()
|
if err := l.Close(); err != nil {
|
||||||
client.Close()
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := client.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
server.Wait()
|
server.Wait()
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue