accounts: check for unrecoverable errors in is_online

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/370/head
Manos Pitsidianakis 2 months ago
parent 264782d228
commit 484712b0c3
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

@ -116,6 +116,19 @@ impl IsOnline {
};
}
}
pub fn is_recoverable(err: &Error) -> bool {
!(err.kind.is_authentication()
|| err.kind.is_configuration()
|| err.kind.is_bug()
|| err.kind.is_external()
|| (err.kind.is_network() && !err.kind.is_network_down())
|| err.kind.is_not_implemented()
|| err.kind.is_not_supported()
|| err.kind.is_protocol_error()
|| err.kind.is_protocol_not_supported()
|| err.kind.is_value_error())
}
}
#[derive(Debug)]
@ -732,6 +745,7 @@ impl Account {
}
None
}
pub fn refresh(&mut self, mailbox_hash: MailboxHash) -> Result<()> {
if let Some(ref refresh_command) = self.settings.conf().refresh_command {
let child = std::process::Command::new("sh")
@ -773,7 +787,9 @@ impl Account {
}
pub fn watch(&mut self) {
if self.settings.account().manual_refresh {
if self.settings.account().manual_refresh
|| matches!(self.is_online, IsOnline::Err { ref value, ..} if !IsOnline::is_recoverable(value))
{
return;
}
@ -1292,17 +1308,7 @@ impl Account {
ref mut retries,
} => {
let ret = Err(value.clone());
if value.kind.is_authentication()
|| value.kind.is_bug()
|| value.kind.is_configuration()
|| value.kind.is_external()
|| (value.kind.is_network() && !value.kind.is_network_down())
|| value.kind.is_not_implemented()
|| value.kind.is_not_supported()
|| value.kind.is_protocol_error()
|| value.kind.is_protocol_not_supported()
|| value.kind.is_value_error()
{
if !IsOnline::is_recoverable(value) {
return ret;
}
let wait = if value.kind.is_timeout()
@ -1417,21 +1423,22 @@ impl Account {
JobRequest::Mailboxes { ref mut handle } => {
if let Ok(Some(mailboxes)) = handle.chan.try_recv() {
if let Err(err) = mailboxes.and_then(|mailboxes| self.init(mailboxes)) {
if err.kind.is_authentication() {
if !IsOnline::is_recoverable(&err) {
self.main_loop_handler.send(ThreadEvent::UIEvent(
UIEvent::Notification {
title: Some(
format!("{}: authentication error", &self.name).into(),
),
source: None,
title: Some(self.name.clone().into()),
source: Some(err.clone()),
body: err.to_string().into(),
kind: Some(crate::types::NotificationType::Error(err.kind)),
},
));
self.is_online.set_err(err);
self.main_loop_handler.send(ThreadEvent::UIEvent(
UIEvent::AccountStatusChange(self.hash, None),
UIEvent::AccountStatusChange(
self.hash,
Some(err.to_string().into()),
),
));
self.is_online.set_err(err);
self.main_loop_handler
.job_executor
.set_job_success(job_id, false);
@ -1551,13 +1558,17 @@ impl Account {
}
}
JobRequest::IsOnline { ref mut handle, .. } => {
if matches!(self.is_online, IsOnline::Err { ref value, ..} if !IsOnline::is_recoverable(value))
{
return true;
}
if let Ok(Some(is_online)) = handle.chan.try_recv() {
self.main_loop_handler.send(ThreadEvent::UIEvent(
UIEvent::AccountStatusChange(self.hash, None),
));
match is_online {
Ok(()) => {
if matches!(self.is_online, IsOnline::Err { ref value, ..} if !value.kind.is_authentication())
if matches!(self.is_online, IsOnline::Err { .. })
|| matches!(self.is_online, IsOnline::Uninit)
{
self.watch();
@ -1566,7 +1577,7 @@ impl Account {
return true;
}
Err(value) => {
self.is_online = IsOnline::Err { value, retries: 1 };
self.is_online.set_err(value);
}
}
}
@ -1585,12 +1596,15 @@ impl Account {
};
}
JobRequest::Refresh { ref mut handle, .. } => {
if matches!(self.is_online, IsOnline::Err { ref value, ..} if !IsOnline::is_recoverable(value))
{
return true;
}
match handle.chan.try_recv() {
Err(_) => { /* canceled */ }
Ok(None) => {}
Ok(Some(Ok(()))) => {
if matches!(self.is_online, IsOnline::Err { ref value, ..} if !value.kind.is_authentication())
{
if matches!(self.is_online, IsOnline::Err { .. }) {
self.watch();
}
self.is_online = IsOnline::True;

@ -1989,7 +1989,7 @@ impl Component for Listing {
&& self.menu_cursor_pos.menu == MenuEntryCursor::Status =>
{
self.cursor_pos = self.menu_cursor_pos;
self.open_status(self.menu_cursor_pos.account, context);
self.change_account(context);
self.set_dirty(true);
self.focus = ListingFocus::Mailbox;
self.ratio = self.prev_ratio;
@ -3184,9 +3184,24 @@ impl Listing {
self.status(context),
)));
}
MenuEntryCursor::Status => {
MenuEntryCursor::Status if context.is_online(account_hash).is_ok() => {
self.open_status(self.cursor_pos.account, context);
}
MenuEntryCursor::Status => {
self.component.unrealize(context);
self.component =
Offline(OfflineListing::new((account_hash, MailboxHash::default())));
self.component.realize(self.id().into(), context);
self.component
.process_event(&mut UIEvent::VisibilityChange(true), context);
self.status = None;
self.cursor_pos.menu = MenuEntryCursor::Mailbox(0);
context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::UpdateStatus(
self.status(context),
)));
}
}
self.sidebar_divider = *account_settings!(context[account_hash].listing.sidebar_divider);
self.set_dirty(true);

@ -220,7 +220,13 @@ impl Component for OfflineListing {
if let Some(msg) = msg.clone() {
self.messages.push(msg);
}
self.dirty = true
self.set_dirty(true);
}
UIEvent::ChangeMode(UIMode::Normal)
| UIEvent::Resize
| UIEvent::ConfigReload { old_settings: _ }
| UIEvent::VisibilityChange(_) => {
self.set_dirty(true);
}
_ => {}
}

Loading…
Cancel
Save