diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2023-11-16 16:23:36 +0100 |
|---|---|---|
| committer | Markus Pettersson <markus.pettersson@mullvad.net> | 2023-12-04 09:06:50 +0100 |
| commit | 2f648dd809195335e7ba84d005b877b55e03fc2c (patch) | |
| tree | 518339e959351fbecc206905971d91a5e1ab5e98 | |
| parent | e31d9e01fa4e4635c4ddead14b18fa7e8381e3f6 (diff) | |
| download | mullvadvpn-2f648dd809195335e7ba84d005b877b55e03fc2c.tar.xz mullvadvpn-2f648dd809195335e7ba84d005b877b55e03fc2c.zip | |
Add proper error handling
| -rw-r--r-- | mullvad-daemon/src/api.rs | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/mullvad-daemon/src/api.rs b/mullvad-daemon/src/api.rs index ef6d2ff106..6074604b89 100644 --- a/mullvad-daemon/src/api.rs +++ b/mullvad-daemon/src/api.rs @@ -38,6 +38,16 @@ pub enum Error { /// Oddly specific. #[error(display = "Very Generic error.")] Generic, + #[error(display = "{}", _0)] + Actor(#[error(source)] ActorError), +} + +#[derive(err_derive::Error, Debug)] +pub enum ActorError { + #[error(display = "AccessModeSelector is not receiving any messages.")] + SendFailed(#[error(source)] mpsc::TrySendError<Message>), + #[error(display = "AccessModeSelector is not responding.")] + NotRunning(#[error(source)] oneshot::Canceled), } #[derive(Clone)] @@ -48,10 +58,10 @@ pub struct AccessModeSelectorHandle { impl AccessModeSelectorHandle { async fn send_command<T>(&self, make_cmd: impl FnOnce(ResponseTx<T>) -> Message) -> Result<T> { let (tx, rx) = oneshot::channel(); - // TODO(markus): Error handling - self.cmd_tx.unbounded_send(make_cmd(tx)).unwrap(); - // TODO(markus): Error handling - rx.await.unwrap() + self.cmd_tx + .unbounded_send(make_cmd(tx)) + .map_err(ActorError::SendFailed)?; + rx.await.map_err(ActorError::NotRunning)? } pub async fn get_access_method(&self) -> Result<AccessMethodSetting> { @@ -90,11 +100,12 @@ impl AccessModeSelectorHandle { pub fn as_stream(&self) -> impl Stream<Item = ApiConnectionMode> { let handle = self.clone(); unfold(handle, |handle| async move { - let connection_mode = handle - .next() - .await - .expect("It should always be safe to `unwrap` a new API connection mode"); - Some((connection_mode, handle)) + match handle.next().await { + Ok(connection_mode) => Some((connection_mode, handle)), + // End this stream in case of failure in `next`. `next` should + // not fail if the actor is in a good state. + Err(_) => None, + } }) } } |
