Fixed ws dial input error being dropped
This commit is contained in:
1 parent
02e3d910a2
commit
b714ee14d5
2 files changed
+38
-1
No files matched your search
@@ -321,14 +321,17 @@ func interact(
|
||||
}()
|
||||
|
||||
// Reading input can't be interrupted, so it has a goroutine of its own,
|
||||
// left blocked if ctx is cancelled first.
|
||||
// left blocked if ctx is cancelled first. Its error, if any, is sent
|
||||
// before lines is closed.
|
||||
lines := make(chan string)
|
||||
inputErr := make(chan error, 1)
|
||||
go func() {
|
||||
defer close(lines)
|
||||
scanner := bufio.NewScanner(input)
|
||||
for scanner.Scan() {
|
||||
lines <- scanner.Text()
|
||||
}
|
||||
inputErr <- scanner.Err()
|
||||
}()
|
||||
|
||||
for {
|
||||
@@ -339,6 +342,11 @@ func interact(
|
||||
return err
|
||||
case line, ok := <-lines:
|
||||
if !ok {
|
||||
err := <-inputErr
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading input: %w", err)
|
||||
}
|
||||
|
||||
// The end of input: stop sending, keep listening.
|
||||
lines = nil
|
||||
continue
|
||||
|
||||
@@ -3,6 +3,7 @@ package ws
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
@@ -281,6 +282,34 @@ func TestDialStdin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Without --message, a failure reading stdin ends dial with an error, unlike
|
||||
// the end of stdin.
|
||||
func TestDialStdinError(t *testing.T) {
|
||||
_, url := wsServer(t)
|
||||
stdin, input := io.Pipe()
|
||||
out := &syncBuffer{}
|
||||
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- dial(context.Background(), stdin, out, dialSettings{
|
||||
url: url,
|
||||
timeout: time.Second,
|
||||
})
|
||||
}()
|
||||
|
||||
waitFor(t, out, `< {"type":"welcome"`)
|
||||
input.CloseWithError(errors.New("disk on fire"))
|
||||
|
||||
select {
|
||||
case err := <-done:
|
||||
if err == nil || !strings.Contains(err.Error(), "reading input: disk on fire") {
|
||||
t.Fatalf("dial = %v; want the input error", err)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("dial did not return after the input error")
|
||||
}
|
||||
}
|
||||
|
||||
// Without --message, dial ends when the server closes the connection.
|
||||
func TestDialStdinServerClose(t *testing.T) {
|
||||
hub, url := wsServer(t)
|
||||
|
||||
Reference in new issue
Block a user