From 2c5f3df47d2737a823a13e44c330cbb138d05aa7 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 9 Jul 2019 04:00:32 -0400 Subject: fix handling of errors from eval --- src/state.rs | 46 ++++++++++++++++++++++++++++------------------ src/tui.rs | 14 +++++++++----- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/state.rs b/src/state.rs index f6c8a78..d291e15 100644 --- a/src/state.rs +++ b/src/state.rs @@ -7,10 +7,8 @@ pub enum Error { #[snafu(display("invalid command index: {}", idx))] InvalidCommandIndex { idx: usize }, - #[snafu(display("error sending message: {}", source))] - Sending { - source: futures::sync::mpsc::SendError, - }, + #[snafu(display("error sending message"))] + Sending, #[snafu(display("error printing output: {}", source))] PrintOutput { source: std::io::Error }, @@ -23,7 +21,7 @@ pub type Result = std::result::Result; #[derive(Debug)] pub enum StateEvent { - Line(usize, String, futures::sync::oneshot::Sender<()>), + Line(usize, String, futures::sync::oneshot::Sender>), } pub struct State { @@ -43,14 +41,21 @@ impl State { &mut self, idx: usize, line: &str, - res: futures::sync::oneshot::Sender<()>, - ) -> Result<()> { - snafu::ensure!( - !self.commands.contains_key(&idx), - InvalidCommandIndex { idx } - ); - let eval = crate::eval::eval(line).context(Eval)?; - self.commands.insert(idx, Command::new(eval, res)); + res: futures::sync::oneshot::Sender>, + ) -> std::result::Result< + (), + (futures::sync::oneshot::Sender>, Error), + > { + if self.commands.contains_key(&idx) { + return Err((res, Error::InvalidCommandIndex { idx })); + } + let eval = crate::eval::eval(line).context(Eval); + match eval { + Ok(eval) => { + self.commands.insert(idx, Command::new(eval, res)); + } + Err(e) => return Err((res, e)), + } Ok(()) } @@ -115,7 +120,12 @@ impl State { line, res, ))) => { - self.eval(idx, &line, res)?; + match self.eval(idx, &line, res) { + Ok(()) => {} + Err((res, e)) => { + res.send(Err(e)).map_err(|_| Error::Sending)?; + } + } did_work = true; } futures::Async::Ready(None) => { @@ -155,8 +165,8 @@ impl State { .remove(&idx) .context(InvalidCommandIndex { idx })? .res - .send(()) - .map_err(|()| unreachable!())?; + .send(Ok(())) + .map_err(|_| Error::Sending)?; did_work = true; } futures::Async::NotReady => {} @@ -188,7 +198,7 @@ impl futures::future::Future for State { struct Command { future: crate::eval::Eval, - res: futures::sync::oneshot::Sender<()>, + res: futures::sync::oneshot::Sender>, cmd: Option, args: Option>, output: Vec, @@ -198,7 +208,7 @@ struct Command { impl Command { fn new( future: crate::eval::Eval, - res: futures::sync::oneshot::Sender<()>, + res: futures::sync::oneshot::Sender>, ) -> Self { Self { future, diff --git a/src/tui.rs b/src/tui.rs index 6708340..221604d 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -8,8 +8,8 @@ pub enum Error { #[snafu(display("error during read: {}", source))] Read { source: crate::readline::Error }, - #[snafu(display("error during eval: {}", source))] - Eval { source: crate::eval::Error }, + #[snafu(display("error from state: {}", source))] + State { source: crate::state::Error }, #[snafu(display("error during sending: {}", source))] Sending { @@ -41,14 +41,14 @@ pub fn tui() { }) .then(move |res| match res { // successful run or empty input means prompt again - Ok(_) - | Err(Error::Eval { + Ok(Ok(())) + | Ok(Err(crate::state::Error::Eval { source: crate::eval::Error::Parser { source: crate::parser::Error::CommandRequired, .. }, - }) => Ok(futures::future::Loop::Continue(idx + 1)), + })) => Ok(futures::future::Loop::Continue(idx + 1)), // eof means we're done Err(Error::Read { source: crate::readline::Error::EOF, @@ -59,6 +59,10 @@ pub fn tui() { error(&e); Ok(futures::future::Loop::Continue(idx + 1)) } + Ok(Err(e)) => { + error(&Error::State { source: e }); + Ok(futures::future::Loop::Continue(idx + 1)) + } }) }) })); -- cgit v1.2.3-54-g00ecf