From d34f374fe7f0e30aa971656a1f451b34b884440e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 24 Aug 2021 08:15:24 -0600 Subject: [PATCH] Beautify error logging Co-Authored-By: Antonio Scandurra --- zed/src/channel.rs | 11 ++++---- zed/src/util.rs | 62 ++++++++++++++++++++++++++++++++++++++++----- zed/src/worktree.rs | 46 ++++++++++++++++++--------------- 3 files changed, 88 insertions(+), 31 deletions(-) diff --git a/zed/src/channel.rs b/zed/src/channel.rs index a82b7d4aee15cfdaad093afdb6823e8543d6a8bd..357546298c586e008aa4d8f412c92f7de0207e6b 100644 --- a/zed/src/channel.rs +++ b/zed/src/channel.rs @@ -1,6 +1,6 @@ use crate::{ rpc::{self, Client}, - util::log_async_errors, + util::TryFutureExt, }; use anyhow::{anyhow, Context, Result}; use gpui::{ @@ -76,7 +76,7 @@ impl ChannelList { pub fn new(rpc: Arc, cx: &mut ModelContext) -> Self { cx.spawn(|this, mut cx| { let rpc = rpc.clone(); - log_async_errors(async move { + async move { let response = rpc .request(proto::GetChannels {}) .await @@ -87,7 +87,8 @@ impl ChannelList { cx.notify(); }); Ok(()) - }) + } + .log_err() }) .detach(); Self { @@ -185,7 +186,7 @@ impl Channel { }); let rpc = self.rpc.clone(); cx.spawn(|this, mut cx| { - log_async_errors(async move { + async move { let request = rpc.request(proto::SendChannelMessage { channel_id, body }); let response = request.await?; this.update(&mut cx, |this, cx| { @@ -205,7 +206,7 @@ impl Channel { } }); Ok(()) - }) + }.log_err() }) .detach(); cx.notify(); diff --git a/zed/src/util.rs b/zed/src/util.rs index 8ca2cfd9b6a897d3eb0e2271b2446194f0e4ee03..9e7a912ce8dfa076e9e8d9ccfbe2d66e96b8d7e2 100644 --- a/zed/src/util.rs +++ b/zed/src/util.rs @@ -1,7 +1,11 @@ -use futures::Future; +use futures::{Future}; pub use gpui::sum_tree::Bias; use rand::prelude::*; -use std::cmp::Ordering; +use std::{ + cmp::Ordering, + pin::Pin, + task::{Context, Poll}, +}; pub fn post_inc(value: &mut usize) -> usize { let prev = *value; @@ -60,12 +64,58 @@ impl Iterator for RandomCharIter { } } -pub async fn log_async_errors(f: F) +pub trait ResultExt { + type Ok; + + fn log_err(self) -> Option; +} + +impl ResultExt for anyhow::Result { + type Ok = T; + + fn log_err(self) -> Option { + match self { + Ok(value) => Some(value), + Err(error) => { + log::error!("{:?}", error); + None + } + } + } +} + +pub trait TryFutureExt { + fn log_err(self) -> LogErrorFuture + where + Self: Sized; +} + +impl TryFutureExt for F where - F: Future>, + F: Future>, { - if let Err(error) = f.await { - log::error!("{}", error) + fn log_err(self) -> LogErrorFuture + where + Self: Sized, + { + LogErrorFuture(self) + } +} + +pub struct LogErrorFuture(F); + +impl Future for LogErrorFuture +where + F: Future>, +{ + type Output = Option; + + fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let inner = unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().0) }; + match inner.poll(cx) { + Poll::Ready(output) => Poll::Ready(output.log_err()), + Poll::Pending => Poll::Pending, + } } } diff --git a/zed/src/worktree.rs b/zed/src/worktree.rs index e121bc5d14e3b2b9469619af0af34f7e38c9ae4c..7b0e212d8d6a42a777e528a5fccf3c9c0d4e5a47 100644 --- a/zed/src/worktree.rs +++ b/zed/src/worktree.rs @@ -9,7 +9,7 @@ use crate::{ language::LanguageRegistry, rpc::{self, proto}, time::{self, ReplicaId}, - util::{log_async_errors, Bias}, + util::{Bias, TryFutureExt}, }; use ::ignore::gitignore::Gitignore; use anyhow::{anyhow, Result}; @@ -330,10 +330,13 @@ impl Worktree { .open_remote_buffer(envelope, cx); cx.background() - .spawn(log_async_errors(async move { - rpc.respond(receipt, response.await?).await?; - Ok(()) - })) + .spawn( + async move { + rpc.respond(receipt, response.await?).await?; + Ok(()) + } + .log_err(), + ) .detach(); Ok(()) @@ -465,22 +468,25 @@ impl Worktree { }); cx.background() - .spawn(log_async_errors(async move { - let (version, mtime) = save.await?; - - rpc.respond( - receipt, - proto::BufferSaved { - worktree_id, - buffer_id, - version: (&version).into(), - mtime: Some(mtime.into()), - }, - ) - .await?; + .spawn( + async move { + let (version, mtime) = save.await?; - Ok(()) - })) + rpc.respond( + receipt, + proto::BufferSaved { + worktree_id, + buffer_id, + version: (&version).into(), + mtime: Some(mtime.into()), + }, + ) + .await?; + + Ok(()) + } + .log_err(), + ) .detach(); Ok(())