Don't unwrap try_recv() on async jobs channels

Job might have been canceled.
jmap-eventsource
Manos Pitsidianakis 2020-12-24 21:56:24 +02:00
parent b2e853dd7b
commit ed826357a3
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
7 changed files with 213 additions and 174 deletions

View File

@ -1115,19 +1115,26 @@ impl Component for Composer {
ViewMode::WaitingForSendResult(_, ref mut handle), ViewMode::WaitingForSendResult(_, ref mut handle),
UIEvent::StatusEvent(StatusEvent::JobFinished(ref job_id)), UIEvent::StatusEvent(StatusEvent::JobFinished(ref job_id)),
) if handle.job_id == *job_id => { ) if handle.job_id == *job_id => {
let result = handle.chan.try_recv().unwrap(); match handle
if let Some(Err(err)) = result { .chan
self.mode = ViewMode::Edit; .try_recv()
context.replies.push_back(UIEvent::Notification( .map_err(|_: futures::channel::oneshot::Canceled| {
None, MeliError::new("Job was canceled")
err.to_string(), }) {
Some(NotificationType::Error(err.kind)), Err(err) | Ok(Some(Err(err))) => {
)); self.mode = ViewMode::Edit;
self.set_dirty(true); context.replies.push_back(UIEvent::Notification(
} else { None,
context err.to_string(),
.replies Some(NotificationType::Error(err.kind)),
.push_back(UIEvent::Action(Tab(Kill(self.id)))); ));
self.set_dirty(true);
}
Ok(None) | Ok(Some(Ok(()))) => {
context
.replies
.push_back(UIEvent::Action(Tab(Kill(self.id))));
}
} }
return false; return false;
} }

View File

@ -119,8 +119,10 @@ impl Component for KeySelection {
.. ..
} => match event { } => match event {
UIEvent::StatusEvent(StatusEvent::JobFinished(ref id)) if *id == handle.job_id => { UIEvent::StatusEvent(StatusEvent::JobFinished(ref id)) if *id == handle.job_id => {
match handle.chan.try_recv().unwrap().unwrap() { match handle.chan.try_recv() {
Ok(keys) => { Err(_) => { /* Job was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
Ok(Some(Ok(keys))) => {
if keys.is_empty() { if keys.is_empty() {
let id = progress_spinner.id(); let id = progress_spinner.id();
if allow_remote_lookup.is_true() { if allow_remote_lookup.is_true() {
@ -192,7 +194,7 @@ impl Component for KeySelection {
widget.set_dirty(true); widget.set_dirty(true);
*self = KeySelection::Loaded { widget, keys }; *self = KeySelection::Loaded { widget, keys };
} }
Err(err) => { Ok(Some(Err(err))) => {
*self = KeySelection::Error { *self = KeySelection::Error {
err, err,
id: ComponentId::new_v4(), id: ComponentId::new_v4(),

View File

@ -1870,8 +1870,11 @@ impl Component for CompactListing {
.unwrap_or(false) => .unwrap_or(false) =>
{ {
let (filter_term, mut handle) = self.search_job.take().unwrap(); let (filter_term, mut handle) = self.search_job.take().unwrap();
let results = handle.chan.try_recv().unwrap().unwrap(); match handle.chan.try_recv() {
self.filter(filter_term, results, context); Err(_) => { /* search was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
Ok(Some(results)) => self.filter(filter_term, results, context),
}
self.set_dirty(true); self.set_dirty(true);
} }
UIEvent::StatusEvent(StatusEvent::JobFinished(ref job_id)) UIEvent::StatusEvent(StatusEvent::JobFinished(ref job_id))
@ -1882,8 +1885,11 @@ impl Component for CompactListing {
.unwrap_or(false) => .unwrap_or(false) =>
{ {
let (search_term, mut handle) = self.select_job.take().unwrap(); let (search_term, mut handle) = self.select_job.take().unwrap();
let results = handle.chan.try_recv().unwrap().unwrap(); match handle.chan.try_recv() {
self.select(&search_term, results, context); Err(_) => { /* search was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
Ok(Some(results)) => self.select(&search_term, results, context),
}
self.set_dirty(true); self.set_dirty(true);
} }
_ => {} _ => {}

View File

@ -1715,8 +1715,11 @@ impl Component for ConversationsListing {
.unwrap_or(false) => .unwrap_or(false) =>
{ {
let (filter_term, mut handle) = self.search_job.take().unwrap(); let (filter_term, mut handle) = self.search_job.take().unwrap();
let results = handle.chan.try_recv().unwrap().unwrap(); match handle.chan.try_recv() {
self.filter(filter_term, results, context); Err(_) => { /* search was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
Ok(Some(results)) => self.filter(filter_term, results, context),
}
self.set_dirty(true); self.set_dirty(true);
} }
_ => {} _ => {}

View File

@ -1362,8 +1362,11 @@ impl Component for PlainListing {
.unwrap_or(false) => .unwrap_or(false) =>
{ {
let (filter_term, mut handle) = self.search_job.take().unwrap(); let (filter_term, mut handle) = self.search_job.take().unwrap();
let results = handle.chan.try_recv().unwrap().unwrap(); match handle.chan.try_recv() {
self.filter(filter_term, results, context); Err(_) => { /* search was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
Ok(Some(results)) => self.filter(filter_term, results, context),
}
self.set_dirty(true); self.set_dirty(true);
} }
_ => {} _ => {}

View File

@ -1607,9 +1607,11 @@ impl Component for MailView {
ref mut handle, ref mut handle,
pending_action: _, pending_action: _,
} if handle.job_id == *job_id => { } if handle.job_id == *job_id => {
let bytes_result = handle.chan.try_recv().unwrap().unwrap(); match handle.chan.try_recv() {
match bytes_result { Err(_) => { /* Job was canceled */ }
Ok(bytes) => { Ok(None) => { /* something happened, perhaps a worker thread panicked */
}
Ok(Some(Ok(bytes))) => {
if context.accounts[&self.coordinates.0] if context.accounts[&self.coordinates.0]
.collection .collection
.get_env(self.coordinates.2) .get_env(self.coordinates.2)
@ -1642,7 +1644,7 @@ impl Component for MailView {
body_text, body_text,
}; };
} }
Err(err) => { Ok(Some(Err(err))) => {
self.state = MailViewState::Error { err }; self.state = MailViewState::Error { err };
} }
} }
@ -1664,8 +1666,11 @@ impl Component for MailView {
} if *our_job_id == *job_id => { } if *our_job_id == *job_id => {
caught = true; caught = true;
self.initialised = false; self.initialised = false;
match handle.chan.try_recv().unwrap().unwrap() { match handle.chan.try_recv() {
Ok(()) => { Err(_) => { /* Job was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */
}
Ok(Some(Ok(()))) => {
*d = AttachmentDisplay::SignedVerified { *d = AttachmentDisplay::SignedVerified {
inner: std::mem::replace( inner: std::mem::replace(
inner, inner,
@ -1675,7 +1680,7 @@ impl Component for MailView {
description: String::new(), description: String::new(),
}; };
} }
Err(error) => { Ok(Some(Err(error))) => {
*d = AttachmentDisplay::SignedFailed { *d = AttachmentDisplay::SignedFailed {
inner: std::mem::replace( inner: std::mem::replace(
inner, inner,
@ -1692,8 +1697,11 @@ impl Component for MailView {
{ {
caught = true; caught = true;
self.initialised = false; self.initialised = false;
match handle.chan.try_recv().unwrap().unwrap() { match handle.chan.try_recv() {
Ok((metadata, decrypted_bytes)) => { Err(_) => { /* Job was canceled */ }
Ok(None) => { /* something happened, perhaps a worker thread panicked */
}
Ok(Some(Ok((metadata, decrypted_bytes)))) => {
let plaintext = let plaintext =
AttachmentBuilder::new(&decrypted_bytes) AttachmentBuilder::new(&decrypted_bytes)
.build(); .build();
@ -1713,7 +1721,7 @@ impl Component for MailView {
description: format!("{:?}", metadata), description: format!("{:?}", metadata),
}; };
} }
Err(error) => { Ok(Some(Err(error))) => {
*d = AttachmentDisplay::EncryptedFailed { *d = AttachmentDisplay::EncryptedFailed {
inner: std::mem::replace( inner: std::mem::replace(
inner, inner,
@ -1814,34 +1822,40 @@ impl Component for MailView {
name: "fetch envelope".into(), name: "fetch envelope".into(),
handle, handle,
on_finish: Some(CallbackFn(Box::new(move |context: &mut Context| { on_finish: Some(CallbackFn(Box::new(move |context: &mut Context| {
let result = receiver.try_recv().unwrap().unwrap(); match receiver.try_recv() {
match result.and_then(|bytes| { Err(_) => { /* Job was canceled */ }
Composer::edit(account_hash, env_hash, &bytes, context) Ok(None) => { /* something happened, perhaps a worker thread panicked */
}) {
Ok(composer) => {
context.replies.push_back(UIEvent::Action(Tab(New(Some(
Box::new(composer),
)))));
} }
Err(err) => { Ok(Some(result)) => {
let err_string = format!( match result.and_then(|bytes| {
"Failed to open envelope {}: {}", Composer::edit(account_hash, env_hash, &bytes, context)
context.accounts[&account_hash] }) {
.collection Ok(composer) => {
.envelopes context.replies.push_back(UIEvent::Action(Tab(New(Some(
.read() Box::new(composer),
.unwrap() )))));
.get(&env_hash) }
.map(|env| env.message_id_display()) Err(err) => {
.unwrap_or_else(|| "Not found".into()), let err_string = format!(
err.to_string() "Failed to open envelope {}: {}",
); context.accounts[&account_hash]
log(&err_string, ERROR); .collection
context.replies.push_back(UIEvent::Notification( .envelopes
Some("Failed to open e-mail".to_string()), .read()
err_string, .unwrap()
Some(NotificationType::Error(err.kind)), .get(&env_hash)
)); .map(|env| env.message_id_display())
.unwrap_or_else(|| "Not found".into()),
err.to_string()
);
log(&err_string, ERROR);
context.replies.push_back(UIEvent::Notification(
Some("Failed to open e-mail".to_string()),
err_string,
Some(NotificationType::Error(err.kind)),
));
}
}
} }
} }
}))), }))),

View File

@ -1585,7 +1585,7 @@ impl Account {
if self.active_jobs.contains_key(job_id) { if self.active_jobs.contains_key(job_id) {
match self.active_jobs.remove(job_id).unwrap() { match self.active_jobs.remove(job_id).unwrap() {
JobRequest::Mailboxes { ref mut handle } => { JobRequest::Mailboxes { ref mut handle } => {
if let Some(mailboxes) = handle.chan.try_recv().unwrap() { if let Ok(Some(mailboxes)) = handle.chan.try_recv() {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange( .send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
self.hash, self.hash,
@ -1620,83 +1620,91 @@ impl Account {
ref mut handle, ref mut handle,
.. ..
} => { } => {
let (payload, rest): (Option<Result<Vec<Envelope>>>, _) =
handle.chan.try_recv().unwrap().unwrap();
debug!("got payload in status for {}", mailbox_hash); debug!("got payload in status for {}", mailbox_hash);
if payload.is_none() { match handle.chan.try_recv() {
debug!("finished in status for {}", mailbox_hash); Err(_) => {
self.mailbox_entries /* canceled */
.entry(mailbox_hash) return true;
.and_modify(|entry| { }
entry.status = MailboxStatus::Available; Ok(None) => {
}); return true;
self.sender }
.send(ThreadEvent::UIEvent(UIEvent::MailboxUpdate(( Ok(Some((None, _))) => {
self.hash, debug!("finished in status for {}", mailbox_hash);
mailbox_hash, self.mailbox_entries
)))) .entry(mailbox_hash)
.unwrap(); .and_modify(|entry| {
return true; entry.status = MailboxStatus::Available;
} });
let handle = if self.backend_capabilities.is_async {
self.job_executor.spawn_specialized(rest.into_future())
} else {
self.job_executor.spawn_blocking(rest.into_future())
};
self.insert_job(
handle.job_id,
JobRequest::Fetch {
mailbox_hash,
handle,
},
);
let payload = payload.unwrap();
if let Err(err) = payload {
self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!("{}: could not fetch mailbox", &self.name)),
err.to_string(),
Some(crate::types::NotificationType::Error(err.kind)),
)))
.expect("Could not send event on main channel");
self.mailbox_entries
.entry(mailbox_hash)
.and_modify(|entry| {
entry.status = MailboxStatus::Failed(err);
});
self.sender
.send(ThreadEvent::UIEvent(UIEvent::MailboxUpdate((
self.hash,
mailbox_hash,
))))
.unwrap();
return true;
}
let envelopes = payload
.unwrap()
.into_iter()
.map(|e| (e.hash(), e))
.collect::<HashMap<EnvelopeHash, Envelope>>();
if let Some(updated_mailboxes) =
self.collection
.merge(envelopes, mailbox_hash, self.sent_mailbox)
{
for f in updated_mailboxes {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::MailboxUpdate((self.hash, f)))) .send(ThreadEvent::UIEvent(UIEvent::MailboxUpdate((
self.hash,
mailbox_hash,
))))
.unwrap();
return true;
}
Ok(Some((Some(Err(err)), _))) => {
self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!("{}: could not fetch mailbox", &self.name)),
err.to_string(),
Some(crate::types::NotificationType::Error(err.kind)),
)))
.expect("Could not send event on main channel");
self.mailbox_entries
.entry(mailbox_hash)
.and_modify(|entry| {
entry.status = MailboxStatus::Failed(err);
});
self.sender
.send(ThreadEvent::UIEvent(UIEvent::MailboxUpdate((
self.hash,
mailbox_hash,
))))
.unwrap();
return true;
}
Ok(Some((Some(Ok(payload)), rest))) => {
let handle = if self.backend_capabilities.is_async {
self.job_executor.spawn_specialized(rest.into_future())
} else {
self.job_executor.spawn_blocking(rest.into_future())
};
self.insert_job(
handle.job_id,
JobRequest::Fetch {
mailbox_hash,
handle,
},
);
let envelopes = payload
.into_iter()
.map(|e| (e.hash(), e))
.collect::<HashMap<EnvelopeHash, Envelope>>();
if let Some(updated_mailboxes) =
self.collection
.merge(envelopes, mailbox_hash, self.sent_mailbox)
{
for f in updated_mailboxes {
self.sender
.send(ThreadEvent::UIEvent(UIEvent::MailboxUpdate((
self.hash, f,
))))
.unwrap();
}
}
self.sender
.send(ThreadEvent::UIEvent(UIEvent::MailboxUpdate((
self.hash,
mailbox_hash,
))))
.unwrap(); .unwrap();
} }
} }
self.sender
.send(ThreadEvent::UIEvent(UIEvent::MailboxUpdate((
self.hash,
mailbox_hash,
))))
.unwrap();
} }
JobRequest::IsOnline { ref mut handle, .. } => { JobRequest::IsOnline { ref mut handle, .. } => {
let is_online = handle.chan.try_recv().unwrap(); if let Ok(Some(is_online)) = handle.chan.try_recv() {
if let Some(is_online) = is_online {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange( .send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
self.hash, self.hash,
@ -1729,9 +1737,10 @@ impl Account {
}; };
} }
JobRequest::Refresh { ref mut handle, .. } => { JobRequest::Refresh { ref mut handle, .. } => {
let r = handle.chan.try_recv().unwrap(); match handle.chan.try_recv() {
match r { Err(_) => { /* canceled */ }
Some(Ok(())) => { Ok(None) => {}
Ok(Some(Ok(()))) => {
if self.is_online.is_err() if self.is_online.is_err()
&& !self && !self
.is_online .is_online
@ -1758,7 +1767,7 @@ impl Account {
.unwrap(); .unwrap();
} }
} }
Some(Err(err)) => { Ok(Some(Err(err))) => {
if !err.kind.is_authentication() { if !err.kind.is_authentication() {
let online_job = self.backend.read().unwrap().is_online(); let online_job = self.backend.read().unwrap().is_online();
if let Ok(online_job) = online_job { if let Ok(online_job) = online_job {
@ -1777,12 +1786,10 @@ impl Account {
))) )))
.unwrap(); .unwrap();
} }
None => {}
} }
} }
JobRequest::SetFlags { ref mut handle, .. } => { JobRequest::SetFlags { ref mut handle, .. } => {
let r = handle.chan.try_recv().unwrap(); if let Ok(Some(Err(err))) = handle.chan.try_recv() {
if let Some(Err(err)) = r {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!("{}: could not set flag", &self.name)), Some(format!("{}: could not set flag", &self.name)),
@ -1797,8 +1804,7 @@ impl Account {
ref bytes, ref bytes,
.. ..
} => { } => {
let r = handle.chan.try_recv().unwrap(); if let Ok(Some(Err(err))) = handle.chan.try_recv() {
if let Some(Err(err)) = r {
melib::log(format!("Could not save message: {}", err), melib::ERROR); melib::log(format!("Could not save message: {}", err), melib::ERROR);
let file = crate::types::create_temp_file(bytes, None, None, false); let file = crate::types::create_temp_file(bytes, None, None, false);
debug!("message saved in {}", file.path.display()); debug!("message saved in {}", file.path.display());
@ -1823,8 +1829,7 @@ impl Account {
} }
JobRequest::SendMessage => {} JobRequest::SendMessage => {}
JobRequest::SendMessageBackground { ref mut handle, .. } => { JobRequest::SendMessageBackground { ref mut handle, .. } => {
let r = handle.chan.try_recv().unwrap(); if let Ok(Some(Err(err))) = handle.chan.try_recv() {
if let Some(Err(err)) = r {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
Some("Could not send message".to_string()), Some("Could not send message".to_string()),
@ -1839,12 +1844,15 @@ impl Account {
ref mut handle, ref mut handle,
.. ..
} => { } => {
if let Err(err) = handle if let Ok(Some(Err(err))) = handle
.chan .chan
.try_recv() .try_recv()
.unwrap() .map_err(|_: futures::channel::oneshot::Canceled| {
.unwrap() MeliError::new("Job was canceled")
.and_then(|bytes| self.save(&bytes, mailbox_hash, None)) })
.map(|r| {
r.map(|r| r.and_then(|bytes| self.save(&bytes, mailbox_hash, None)))
})
{ {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
@ -1856,8 +1864,7 @@ impl Account {
} }
} }
JobRequest::DeleteMessages { ref mut handle, .. } => { JobRequest::DeleteMessages { ref mut handle, .. } => {
let r = handle.chan.try_recv().unwrap(); if let Ok(Some(Err(err))) = handle.chan.try_recv() {
if let Some(Err(err)) = r {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!("{}: could not delete message", &self.name)), Some(format!("{}: could not delete message", &self.name)),
@ -1872,8 +1879,7 @@ impl Account {
ref mut handle, ref mut handle,
.. ..
} => { } => {
let r = handle.chan.try_recv().unwrap(); if let Ok(Some(r)) = handle.chan.try_recv() {
if let Some(r) = r {
match r { match r {
Err(err) => { Err(err) => {
self.sender self.sender
@ -1956,9 +1962,10 @@ impl Account {
ref mut handle, ref mut handle,
.. ..
} => { } => {
let r = handle.chan.try_recv().unwrap(); match handle.chan.try_recv() {
match r { Err(_) => { /* canceled */ }
Some(Err(err)) => { Ok(None) => {}
Ok(Some(Err(err))) => {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!("{}: could not delete mailbox", &self.name)), Some(format!("{}: could not delete mailbox", &self.name)),
@ -1967,7 +1974,7 @@ impl Account {
))) )))
.expect("Could not send event on main channel"); .expect("Could not send event on main channel");
} }
Some(Ok(mut mailboxes)) => { Ok(Some(Ok(mut mailboxes))) => {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::MailboxDelete(( .send(ThreadEvent::UIEvent(UIEvent::MailboxDelete((
self.hash, self.hash,
@ -2022,15 +2029,15 @@ impl Account {
))) )))
.expect("Could not send event on main channel"); .expect("Could not send event on main channel");
} }
None => {}
} }
} }
//JobRequest::RenameMailbox, //JobRequest::RenameMailbox,
JobRequest::Search { .. } | JobRequest::AsBytes { .. } => {} JobRequest::Search { .. } | JobRequest::AsBytes { .. } => {}
JobRequest::SetMailboxPermissions { ref mut handle, .. } => { JobRequest::SetMailboxPermissions { ref mut handle, .. } => {
let r = handle.chan.try_recv().unwrap(); match handle.chan.try_recv() {
match r { Err(_) => { /* canceled */ }
Some(Err(err)) => { Ok(None) => {}
Ok(Some(Err(err))) => {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!( Some(format!(
@ -2042,7 +2049,7 @@ impl Account {
))) )))
.expect("Could not send event on main channel"); .expect("Could not send event on main channel");
} }
Some(Ok(_)) => { Ok(Some(Ok(_))) => {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!( Some(format!(
@ -2054,13 +2061,13 @@ impl Account {
))) )))
.expect("Could not send event on main channel"); .expect("Could not send event on main channel");
} }
None => {}
} }
} }
JobRequest::SetMailboxSubscription { ref mut handle, .. } => { JobRequest::SetMailboxSubscription { ref mut handle, .. } => {
let r = handle.chan.try_recv().unwrap(); match handle.chan.try_recv() {
match r { Err(_) => { /* canceled */ }
Some(Err(err)) => { Ok(None) => {}
Ok(Some(Err(err))) => {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!( Some(format!(
@ -2072,7 +2079,7 @@ impl Account {
))) )))
.expect("Could not send event on main channel"); .expect("Could not send event on main channel");
} }
Some(Ok(_)) => { Ok(Some(Ok(_))) => {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!( Some(format!(
@ -2084,14 +2091,11 @@ impl Account {
))) )))
.expect("Could not send event on main channel"); .expect("Could not send event on main channel");
} }
None => {}
} }
} }
JobRequest::Watch { ref mut handle } => { JobRequest::Watch { ref mut handle } => {
debug!("JobRequest::Watch finished??? "); debug!("JobRequest::Watch finished??? ");
let r = handle.chan.try_recv().unwrap(); if let Ok(Some(Err(err))) = handle.chan.try_recv() {
debug!("JobRequest::Watch {:?}", r);
if let Some(Err(err)) = r {
if err.kind.is_timeout() { if err.kind.is_timeout() {
self.watch(); self.watch();
} else { } else {
@ -2112,9 +2116,8 @@ impl Account {
ref mut on_finish, ref mut on_finish,
logging_level, logging_level,
} => { } => {
let r = handle.chan.try_recv().unwrap(); match handle.chan.try_recv() {
match r { Ok(Some(Err(err))) => {
Some(Err(err)) => {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
Some(format!("{}: {} failed", &self.name, name,)), Some(format!("{}: {} failed", &self.name, name,)),
@ -2123,7 +2126,7 @@ impl Account {
))) )))
.expect("Could not send event on main channel"); .expect("Could not send event on main channel");
} }
Some(Ok(())) if on_finish.is_none() => { Ok(Some(Ok(()))) if on_finish.is_none() => {
if logging_level <= melib::LoggingLevel::INFO { if logging_level <= melib::LoggingLevel::INFO {
self.sender self.sender
.send(ThreadEvent::UIEvent(UIEvent::Notification( .send(ThreadEvent::UIEvent(UIEvent::Notification(
@ -2134,7 +2137,8 @@ impl Account {
.expect("Could not send event on main channel"); .expect("Could not send event on main channel");
} }
} }
Some(Ok(())) | None => {} Err(_) => { /* canceled */ }
Ok(Some(Ok(()))) | Ok(None) => {}
} }
if on_finish.is_some() { if on_finish.is_some() {
self.sender self.sender