Improve IMAP idle timeout error handling

Return proper cause and avoid matching on nested Result
This commit is contained in:
Alexander Krotov
2019-12-08 20:01:57 +03:00
committed by Floris Bruynooghe
parent 33793d878b
commit cd951ad396

View File

@@ -19,7 +19,7 @@ pub enum Error {
IdleProtocolFailed(#[cause] async_imap::error::Error), IdleProtocolFailed(#[cause] async_imap::error::Error),
#[fail(display = "IMAP IDLE protocol timed out")] #[fail(display = "IMAP IDLE protocol timed out")]
IdleTimeout(String), IdleTimeout(#[cause] async_std::future::TimeoutError),
#[fail(display = "IMAP server does not have IDLE capability")] #[fail(display = "IMAP server does not have IDLE capability")]
IdleAbilityMissing, IdleAbilityMissing,
@@ -97,22 +97,24 @@ impl Imap {
// if we can't properly terminate the idle // if we can't properly terminate the idle
// protocol let's break the connection. // protocol let's break the connection.
let res = let res =
async_std::future::timeout(Duration::from_secs(15), handle.done()); async_std::future::timeout(Duration::from_secs(15), handle.done())
match res.await { .await
Ok(Ok(session)) => { .map_err(|err| {
self.trigger_reconnect();
Error::IdleTimeout(err)
})?;
match res {
Ok(session) => {
*self.session.lock().await = Some(Session::Secure(session)); *self.session.lock().await = Some(Session::Secure(session));
} }
Ok(Err(err)) => { Err(err) => {
// if we cannot terminate IDLE it probably // if we cannot terminate IDLE it probably
// means that we waited long (with idle_wait) // means that we waited long (with idle_wait)
// but the network went away/changed // but the network went away/changed
self.trigger_reconnect(); self.trigger_reconnect();
return Err(Error::IdleProtocolFailed(err)); return Err(Error::IdleProtocolFailed(err));
} }
Err(err) => {
self.trigger_reconnect();
return Err(Error::IdleTimeout(err.to_string()));
}
} }
} }
IdleHandle::Insecure(mut handle) => { IdleHandle::Insecure(mut handle) => {
@@ -149,22 +151,24 @@ impl Imap {
// if we can't properly terminate the idle // if we can't properly terminate the idle
// protocol let's break the connection. // protocol let's break the connection.
let res = let res =
async_std::future::timeout(Duration::from_secs(15), handle.done()); async_std::future::timeout(Duration::from_secs(15), handle.done())
match res.await { .await
Ok(Ok(session)) => { .map_err(|err| {
self.trigger_reconnect();
Error::IdleTimeout(err)
})?;
match res {
Ok(session) => {
*self.session.lock().await = Some(Session::Insecure(session)); *self.session.lock().await = Some(Session::Insecure(session));
} }
Ok(Err(err)) => { Err(err) => {
// if we cannot terminate IDLE it probably // if we cannot terminate IDLE it probably
// means that we waited long (with idle_wait) // means that we waited long (with idle_wait)
// but the network went away/changed // but the network went away/changed
self.trigger_reconnect(); self.trigger_reconnect();
return Err(Error::IdleProtocolFailed(err)); return Err(Error::IdleProtocolFailed(err));
} }
Err(err) => {
self.trigger_reconnect();
return Err(Error::IdleTimeout(err.to_string()));
}
} }
} }
} }