mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 21:06:31 +03:00
imap: use anyhow for error handling
This commit is contained in:
@@ -6,9 +6,8 @@
|
|||||||
use std::{cmp, cmp::max, collections::BTreeMap};
|
use std::{cmp, cmp::max, collections::BTreeMap};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, format_err, Context as _, Result};
|
use anyhow::{anyhow, bail, format_err, Context as _, Result};
|
||||||
use async_imap::{
|
use async_imap::types::{
|
||||||
error::Result as ImapResult,
|
Fetch, Flag, Mailbox, Name, NameAttribute, Quota, QuotaRoot, UnsolicitedResponse,
|
||||||
types::{Fetch, Flag, Mailbox, Name, NameAttribute, Quota, QuotaRoot, UnsolicitedResponse},
|
|
||||||
};
|
};
|
||||||
use async_std::channel::Receiver;
|
use async_std::channel::Receiver;
|
||||||
use async_std::prelude::*;
|
use async_std::prelude::*;
|
||||||
@@ -259,7 +258,7 @@ impl Imap {
|
|||||||
|
|
||||||
let oauth2 = self.config.oauth2;
|
let oauth2 = self.config.oauth2;
|
||||||
|
|
||||||
let connection_res: ImapResult<Client> = if self.config.lp.security == Socket::Starttls
|
let connection_res: Result<Client> = if self.config.lp.security == Socket::Starttls
|
||||||
|| self.config.lp.security == Socket::Plain
|
|| self.config.lp.security == Socket::Plain
|
||||||
{
|
{
|
||||||
let config = &mut self.config;
|
let config = &mut self.config;
|
||||||
@@ -354,7 +353,7 @@ impl Imap {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
Err((err, _)) => {
|
Err(err) => {
|
||||||
let imap_user = self.config.lp.user.to_owned();
|
let imap_user = self.config.lp.user.to_owned();
|
||||||
let message = stock_str::cannot_login(context, &imap_user).await;
|
let message = stock_str::cannot_login(context, &imap_user).await;
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ use std::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_imap::{
|
use anyhow::{Context as _, Result};
|
||||||
error::{Error as ImapError, Result as ImapResult},
|
|
||||||
Client as ImapClient,
|
use async_imap::Client as ImapClient;
|
||||||
};
|
|
||||||
|
|
||||||
use async_smtp::ServerAddress;
|
use async_smtp::ServerAddress;
|
||||||
use async_std::net::{self, TcpStream};
|
use async_std::net::{self, TcpStream};
|
||||||
@@ -40,24 +39,12 @@ impl DerefMut for Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
pub async fn login(
|
pub async fn login(self, username: &str, password: &str) -> Result<Session> {
|
||||||
self,
|
let Client { inner, .. } = self;
|
||||||
username: &str,
|
|
||||||
password: &str,
|
|
||||||
) -> std::result::Result<Session, (ImapError, Self)> {
|
|
||||||
let Client { inner, is_secure } = self;
|
|
||||||
let session = inner
|
let session = inner
|
||||||
.login(username, password)
|
.login(username, password)
|
||||||
.await
|
.await
|
||||||
.map_err(|(err, client)| {
|
.map_err(|(err, _client)| err)?;
|
||||||
(
|
|
||||||
err,
|
|
||||||
Client {
|
|
||||||
is_secure,
|
|
||||||
inner: client,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
Ok(Session { inner: session })
|
Ok(Session { inner: session })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,21 +52,12 @@ impl Client {
|
|||||||
self,
|
self,
|
||||||
auth_type: &str,
|
auth_type: &str,
|
||||||
authenticator: impl async_imap::Authenticator,
|
authenticator: impl async_imap::Authenticator,
|
||||||
) -> std::result::Result<Session, (ImapError, Self)> {
|
) -> Result<Session> {
|
||||||
let Client { inner, is_secure } = self;
|
let Client { inner, .. } = self;
|
||||||
let session =
|
let session = inner
|
||||||
inner
|
.authenticate(auth_type, authenticator)
|
||||||
.authenticate(auth_type, authenticator)
|
.await
|
||||||
.await
|
.map_err(|(err, _client)| err)?;
|
||||||
.map_err(|(err, client)| {
|
|
||||||
(
|
|
||||||
err,
|
|
||||||
Client {
|
|
||||||
is_secure,
|
|
||||||
inner: client,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
Ok(Session { inner: session })
|
Ok(Session { inner: session })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +65,7 @@ impl Client {
|
|||||||
addr: impl net::ToSocketAddrs,
|
addr: impl net::ToSocketAddrs,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
) -> ImapResult<Self> {
|
) -> Result<Self> {
|
||||||
let stream = TcpStream::connect(addr).await?;
|
let stream = TcpStream::connect(addr).await?;
|
||||||
let tls = dc_build_tls(strict_tls);
|
let tls = dc_build_tls(strict_tls);
|
||||||
let tls_stream: Box<dyn SessionStream> = Box::new(tls.connect(domain, stream).await?);
|
let tls_stream: Box<dyn SessionStream> = Box::new(tls.connect(domain, stream).await?);
|
||||||
@@ -96,7 +74,7 @@ impl Client {
|
|||||||
let _greeting = client
|
let _greeting = client
|
||||||
.read_response()
|
.read_response()
|
||||||
.await
|
.await
|
||||||
.ok_or_else(|| ImapError::Bad("failed to read greeting".to_string()))?;
|
.context("failed to read greeting")?;
|
||||||
|
|
||||||
Ok(Client {
|
Ok(Client {
|
||||||
is_secure: true,
|
is_secure: true,
|
||||||
@@ -104,14 +82,14 @@ impl Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn connect_insecure(addr: impl net::ToSocketAddrs) -> ImapResult<Self> {
|
pub async fn connect_insecure(addr: impl net::ToSocketAddrs) -> Result<Self> {
|
||||||
let stream: Box<dyn SessionStream> = Box::new(TcpStream::connect(addr).await?);
|
let stream: Box<dyn SessionStream> = Box::new(TcpStream::connect(addr).await?);
|
||||||
|
|
||||||
let mut client = ImapClient::new(stream);
|
let mut client = ImapClient::new(stream);
|
||||||
let _greeting = client
|
let _greeting = client
|
||||||
.read_response()
|
.read_response()
|
||||||
.await
|
.await
|
||||||
.ok_or_else(|| ImapError::Bad("failed to read greeting".to_string()))?;
|
.context("failed to read greeting")?;
|
||||||
|
|
||||||
Ok(Client {
|
Ok(Client {
|
||||||
is_secure: false,
|
is_secure: false,
|
||||||
@@ -123,15 +101,11 @@ impl Client {
|
|||||||
target_addr: &ServerAddress,
|
target_addr: &ServerAddress,
|
||||||
strict_tls: bool,
|
strict_tls: bool,
|
||||||
socks5_config: Socks5Config,
|
socks5_config: Socks5Config,
|
||||||
) -> ImapResult<Self> {
|
) -> Result<Self> {
|
||||||
let socks5_stream: Box<dyn SessionStream> = Box::new(
|
let socks5_stream: Box<dyn SessionStream> = Box::new(
|
||||||
match socks5_config
|
socks5_config
|
||||||
.connect(target_addr, Some(Duration::from_secs(IMAP_TIMEOUT)))
|
.connect(target_addr, Some(Duration::from_secs(IMAP_TIMEOUT)))
|
||||||
.await
|
.await?,
|
||||||
{
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(e) => return ImapResult::Err(async_imap::error::Error::Bad(e.to_string())),
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let tls = dc_build_tls(strict_tls);
|
let tls = dc_build_tls(strict_tls);
|
||||||
@@ -142,7 +116,7 @@ impl Client {
|
|||||||
let _greeting = client
|
let _greeting = client
|
||||||
.read_response()
|
.read_response()
|
||||||
.await
|
.await
|
||||||
.ok_or_else(|| ImapError::Bad("failed to read greeting".to_string()))?;
|
.context("failed to read greeting")?;
|
||||||
|
|
||||||
Ok(Client {
|
Ok(Client {
|
||||||
is_secure: true,
|
is_secure: true,
|
||||||
@@ -153,22 +127,18 @@ impl Client {
|
|||||||
pub async fn connect_insecure_socks5(
|
pub async fn connect_insecure_socks5(
|
||||||
target_addr: &ServerAddress,
|
target_addr: &ServerAddress,
|
||||||
socks5_config: Socks5Config,
|
socks5_config: Socks5Config,
|
||||||
) -> ImapResult<Self> {
|
) -> Result<Self> {
|
||||||
let socks5_stream: Box<dyn SessionStream> = Box::new(
|
let socks5_stream: Box<dyn SessionStream> = Box::new(
|
||||||
match socks5_config
|
socks5_config
|
||||||
.connect(target_addr, Some(Duration::from_secs(IMAP_TIMEOUT)))
|
.connect(target_addr, Some(Duration::from_secs(IMAP_TIMEOUT)))
|
||||||
.await
|
.await?,
|
||||||
{
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(e) => return ImapResult::Err(async_imap::error::Error::Bad(e.to_string())),
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut client = ImapClient::new(socks5_stream);
|
let mut client = ImapClient::new(socks5_stream);
|
||||||
let _greeting = client
|
let _greeting = client
|
||||||
.read_response()
|
.read_response()
|
||||||
.await
|
.await
|
||||||
.ok_or_else(|| ImapError::Bad("failed to read greeting".to_string()))?;
|
.context("failed to read greeting")?;
|
||||||
|
|
||||||
Ok(Client {
|
Ok(Client {
|
||||||
is_secure: false,
|
is_secure: false,
|
||||||
@@ -176,7 +146,7 @@ impl Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn secure(self, domain: &str, strict_tls: bool) -> ImapResult<Client> {
|
pub async fn secure(self, domain: &str, strict_tls: bool) -> Result<Client> {
|
||||||
if self.is_secure {
|
if self.is_secure {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user