diff --git a/internal/jsonrpc2_v2/serve.go b/internal/jsonrpc2_v2/serve.go index 78259b1e4a4..20cc3789b53 100644 --- a/internal/jsonrpc2_v2/serve.go +++ b/internal/jsonrpc2_v2/serve.go @@ -133,16 +133,21 @@ func isClosingError(err error) bool { if err == nil { 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) { err = wrapped } - // was it based on an EOF error? + // Was it based on an EOF error? if err == io.EOF { 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 // change. This is not ideal, but since the worst that could happen here is // some superfluous logging, it is acceptable. diff --git a/internal/jsonrpc2_v2/serve_test.go b/internal/jsonrpc2_v2/serve_test.go index 22f18cd18ba..7f1dbc3c97e 100644 --- a/internal/jsonrpc2_v2/serve_test.go +++ b/internal/jsonrpc2_v2/serve_test.go @@ -99,11 +99,11 @@ func TestServe(t *testing.T) { if err != nil { t.Fatal(err) } - conn, shutdown, err := newFake(ctx, fake) + conn, shutdown, err := newFake(t, ctx, fake) if err != nil { t.Fatal(err) } - defer shutdown(ctx) + defer shutdown() var got msg if err := conn.Call(ctx, "ping", &msg{"ting"}).Await(ctx, &got); err != nil { 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) server, err := jsonrpc2.Serve(ctx, l, jsonrpc2.ConnectionOptions{ Handler: fakeHandler{}, @@ -132,9 +132,13 @@ func newFake(ctx context.Context, l jsonrpc2.Listener) (*jsonrpc2.Connection, fu if err != nil { return nil, nil, err } - return client, func(ctx context.Context) { - l.Close() - client.Close() + return client, func() { + if err := l.Close(); err != nil { + t.Fatal(err) + } + if err := client.Close(); err != nil { + t.Fatal(err) + } server.Wait() }, nil }