on master help sign in
Handle stderr
7b61c63Blaž Hrastnik
helix-dap/src/client.rs+6−2
@@ -62,10 +62,11 @@ impl Client {
62 pub fn streams(
62 pub fn streams(
63 rx: Box<dyn AsyncBufRead + Unpin + Send>,
63 rx: Box<dyn AsyncBufRead + Unpin + Send>,
64 tx: Box<dyn AsyncWrite + Unpin + Send>,
64 tx: Box<dyn AsyncWrite + Unpin + Send>,
65+ err: Option<Box<dyn AsyncBufRead + Unpin + Send>>,
65 id: usize,
66 id: usize,
66 process: Option<Child>,
67 process: Option<Child>,
67 ) -> Result<(Self, UnboundedReceiver<Payload>)> {
68 ) -> Result<(Self, UnboundedReceiver<Payload>)> {
68− let (server_rx, server_tx) = Transport::start(rx, tx, id);
69+ let (server_rx, server_tx) = Transport::start(rx, tx, err, id);
69 let (client_rx, client_tx) = unbounded_channel();
70 let (client_rx, client_tx) = unbounded_channel();
70
71
71 let client = Self {
72 let client = Self {
@@ -92,7 +93,7 @@ impl Client {
92 ) -> Result<(Self, UnboundedReceiver<Payload>)> {
93 ) -> Result<(Self, UnboundedReceiver<Payload>)> {
93 let stream = TcpStream::connect(addr).await?;
94 let stream = TcpStream::connect(addr).await?;
94 let (rx, tx) = stream.into_split();
95 let (rx, tx) = stream.into_split();
95− Self::streams(Box::new(BufReader::new(rx)), Box::new(tx), id, None)
96+ Self::streams(Box::new(BufReader::new(rx)), Box::new(tx), None, id, None)
96 }
97 }
97
98
98 pub fn stdio(
99 pub fn stdio(
@@ -113,10 +114,12 @@ impl Client {
113 // TODO: do we need bufreader/writer here? or do we use async wrappers on unblock?
114 // TODO: do we need bufreader/writer here? or do we use async wrappers on unblock?
114 let writer = BufWriter::new(process.stdin.take().expect("Failed to open stdin"));
115 let writer = BufWriter::new(process.stdin.take().expect("Failed to open stdin"));
115 let reader = BufReader::new(process.stdout.take().expect("Failed to open stdout"));
116 let reader = BufReader::new(process.stdout.take().expect("Failed to open stdout"));
117+ let errors = BufReader::new(process.stderr.take().expect("Failed to open stderr"));
116
118
117 Self::streams(
119 Self::streams(
118 Box::new(BufReader::new(reader)),
120 Box::new(BufReader::new(reader)),
119 Box::new(writer),
121 Box::new(writer),
122+ Some(Box::new(BufReader::new(errors))),
120 id,
123 id,
121 Some(process),
124 Some(process),
122 )
125 )
@@ -167,6 +170,7 @@ impl Client {
167 Self::streams(
170 Self::streams(
168 Box::new(BufReader::new(rx)),
171 Box::new(BufReader::new(rx)),
169 Box::new(tx),
172 Box::new(tx),
173+ None,
170 id,
174 id,
171 Some(process),
175 Some(process),
172 )
176 )
helix-dap/src/transport.rs+28
@@ -53,6 +53,7 @@ impl Transport {
53 pub fn start(
53 pub fn start(
54 server_stdout: Box<dyn AsyncBufRead + Unpin + Send>,
54 server_stdout: Box<dyn AsyncBufRead + Unpin + Send>,
55 server_stdin: Box<dyn AsyncWrite + Unpin + Send>,
55 server_stdin: Box<dyn AsyncWrite + Unpin + Send>,
56+ server_stderr: Option<Box<dyn AsyncBufRead + Unpin + Send>>,
56 id: usize,
57 id: usize,
57 ) -> (UnboundedReceiver<Payload>, UnboundedSender<Request>) {
58 ) -> (UnboundedReceiver<Payload>, UnboundedSender<Request>) {
58 let (client_tx, rx) = unbounded_channel();
59 let (client_tx, rx) = unbounded_channel();
@@ -67,6 +68,9 @@ impl Transport {
67
68
68 tokio::spawn(Self::recv(transport.clone(), server_stdout, client_tx));
69 tokio::spawn(Self::recv(transport.clone(), server_stdout, client_tx));
69 tokio::spawn(Self::send(transport, server_stdin, client_rx));
70 tokio::spawn(Self::send(transport, server_stdin, client_rx));
71+ if let Some(stderr) = server_stderr {
72+ tokio::spawn(Self::err(stderr));
73+ }
70
74
71 (rx, tx)
75 (rx, tx)
72 }
76 }
@@ -117,6 +121,17 @@ impl Transport {
117 Ok(output?)
121 Ok(output?)
118 }
122 }
119
123
124+ async fn recv_server_error(
125+ err: &mut (impl AsyncBufRead + Unpin + Send),
126+ buffer: &mut String,
127+ ) -> Result<()> {
128+ buffer.truncate(0);
129+ err.read_line(buffer).await?;
130+ error!("err <- {}", buffer);
131+
132+ Ok(())
133+ }
134+
120 async fn send_payload_to_server(
135 async fn send_payload_to_server(
121 &self,
136 &self,
122 server_stdin: &mut Box<dyn AsyncWrite + Unpin + Send>,
137 server_stdin: &mut Box<dyn AsyncWrite + Unpin + Send>,
@@ -243,4 +258,17 @@ impl Transport {
243 .unwrap()
258 .unwrap()
244 }
259 }
245 }
260 }
261+
262+ async fn err(mut server_stderr: Box<dyn AsyncBufRead + Unpin + Send>) {
263+ let mut recv_buffer = String::new();
264+ loop {
265+ match Self::recv_server_error(&mut server_stderr, &mut recv_buffer).await {
266+ Ok(_) => {}
267+ Err(err) => {
268+ error!("err: <- {:?}", err);
269+ break;
270+ }
271+ }
272+ }
273+ }
246}
274}