Skip to content

Commit

Permalink
Better error formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewhickman committed Jun 6, 2023
1 parent a13793c commit 12a7585
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 64 deletions.
24 changes: 2 additions & 22 deletions src/app/body/address/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fmt::Write, io, mem, str::FromStr, sync::Arc};
use std::{mem, str::FromStr, sync::Arc};

use druid::{
widget::{
Expand Down Expand Up @@ -43,7 +43,7 @@ pub(in crate::app) fn build(parent: WidgetId) -> impl Widget<AddressState> {
if let Err(err) = data.uri.result() {
err.clone()
} else if let RequestState::ConnectFailed(err) = data.request_state() {
fmt_connect_err(err)
err.clone()
} else {
String::default()
}
Expand Down Expand Up @@ -207,23 +207,3 @@ fn validate_uri(s: &String) -> Result<Uri, String> {
}
Ok(uri)
}

fn fmt_connect_err(err: &anyhow::Error) -> String {
if let Some(err) = err.root_cause().downcast_ref::<io::Error>() {
format!("failed to connect: {}", err)
} else {
let mut s = String::new();
for cause in err.chain() {
if !s.is_empty() {
s.push_str(": ");
}
let len = s.len();
write!(s, "{}", cause).unwrap();
if s[..len].contains(&s[len..]) {
s.truncate(len.saturating_sub(2));
break;
}
}
s
}
}
4 changes: 2 additions & 2 deletions src/app/body/method/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use druid::{

use crate::{
app::{
body::{method::MethodTabState, RequestState},
body::{fmt_connect_err, method::MethodTabState, RequestState},
command,
},
grpc,
Expand Down Expand Up @@ -128,7 +128,7 @@ impl MethodTabController {
}
Err(err) => {
data.address
.set_request_state(RequestState::ConnectFailed(err));
.set_request_state(RequestState::ConnectFailed(fmt_connect_err(&err)));
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/app/body/method/stream/item.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::sync::Arc;

use anyhow::Error;
use druid::{widget::TextBox, Application};
use druid::{Data, Lens, Widget, WidgetExt as _};
Expand All @@ -23,7 +21,7 @@ impl State {
State { body: json }
}

pub fn from_response(result: Result<JsonText, Arc<Error>>) -> Self {
pub fn from_response(result: Result<JsonText, Error>) -> Self {
let body = result.unwrap_or_else(|err| JsonText::plain_text(format!("{:?}", err)));

State { body }
Expand Down
8 changes: 2 additions & 6 deletions src/app/body/method/stream/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod item;

use std::{iter, sync::Arc, time::Duration};
use std::{iter, time::Duration};

use anyhow::Error;
use druid::{
Expand Down Expand Up @@ -141,11 +141,7 @@ impl State {
});
}

pub fn add_response(
&mut self,
result: Result<JsonText, Arc<Error>>,
duration: Option<Duration>,
) {
pub fn add_response(&mut self, result: Result<JsonText, Error>, duration: Option<Duration>) {
for item in self.items.iter_mut() {
item.expanded = false;
}
Expand Down
15 changes: 11 additions & 4 deletions src/app/body/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ mod options;

pub(in crate::app) use self::method::StreamState;

use std::{collections::BTreeMap, mem, ops::Bound, sync::Arc};
use std::{collections::BTreeMap, io, mem, ops::Bound, sync::Arc};

use druid::{widget::ViewSwitcher, ArcStr, Data, Lens, Widget, WidgetExt as _};
use iter_set::Inclusion;
use prost_reflect::{MethodDescriptor, ServiceDescriptor};

use self::{method::MethodTabState, options::OptionsTabState};
use crate::{
app::{command, metadata, sidebar::service::ServiceOptions},
grpc,
app::{command, fmt_err, metadata, sidebar::service::ServiceOptions},
json::JsonText,
widget::{tabs, TabId, TabLabelState, TabsData, TabsDataChange},
};
Expand All @@ -29,7 +28,7 @@ pub enum RequestState {
NotStarted,
ConnectInProgress,
Connected,
ConnectFailed(grpc::Error),
ConnectFailed(String),
Active,
}

Expand Down Expand Up @@ -500,3 +499,11 @@ impl TabsData for State {
&& !cmd.is(command::FINISH)
}
}

pub fn fmt_connect_err(err: &anyhow::Error) -> String {
if let Some(err) = err.root_cause().downcast_ref::<io::Error>() {
format!("failed to connect: {}", err)
} else {
fmt_err(err)
}
}
4 changes: 2 additions & 2 deletions src/app/body/options/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use druid::{

use crate::{
app::{
body::{options::OptionsTabState, RequestState},
body::{fmt_connect_err, options::OptionsTabState, RequestState},
command,
},
grpc,
Expand Down Expand Up @@ -123,7 +123,7 @@ impl OptionsTabController {
}
Err(err) => {
data.default_address
.set_request_state(RequestState::ConnectFailed(err));
.set_request_state(RequestState::ConnectFailed(fmt_connect_err(&err)));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/delegate.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use druid::{AppDelegate, Command, DelegateCtx, Env, Handled, Target};

use crate::app::{self, command};
use crate::app::{self, command, fmt_err};

pub(in crate::app) fn build() -> impl AppDelegate<app::State> {
Delegate
Expand All @@ -20,7 +20,7 @@ impl AppDelegate<app::State> for Delegate {
tracing::debug!("Received command: {:?}", cmd);
if let Some(file) = cmd.get(druid::commands::OPEN_FILE) {
if let Err(err) = data.sidebar.add_from_path(file.path()) {
data.error = Some(format!("Error loading file: {:?}", err));
data.error = Some(format!("Error loading file: {}", fmt_err(&err)));
} else {
data.error = None;
}
Expand Down
18 changes: 18 additions & 0 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,21 @@ impl State {
SidebarLens
}
}

fn fmt_err(err: &anyhow::Error) -> String {
use std::fmt::Write;

let mut s = String::new();
for cause in err.chain() {
if !s.is_empty() {
s.push_str(": ");
}
let len = s.len();
write!(s, "{}", cause).unwrap();
if s[..len].contains(&s[len..]) {
s.truncate(len.saturating_sub(2));
break;
}
}
s
}
22 changes: 6 additions & 16 deletions src/grpc/channel.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{sync::Arc, time::SystemTime};

use anyhow::{Context, Error};
use anyhow::{Context, Error, Result};
use dashmap::{mapref::entry::Entry, DashMap};
use futures::future::BoxFuture;
use http::{uri::Scheme, Uri};
Expand All @@ -11,8 +11,6 @@ use rustls::RootCertStore;
use tokio::sync::Mutex;
use tonic::transport::Channel;

use crate::grpc;

static CHANNELS: Lazy<DashMap<ChannelKey, Arc<Mutex<ChannelState>>>> = Lazy::new(Default::default);

#[derive(Clone, Hash, PartialEq, Eq)]
Expand All @@ -22,12 +20,12 @@ struct ChannelKey {
}

enum ChannelState {
Pending(BoxFuture<'static, Result<Channel, grpc::Error>>),
Pending(BoxFuture<'static, Result<Channel>>),
Ready(Channel),
Error,
}

pub async fn get(uri: &Uri, verify_certs: bool) -> Result<Channel, grpc::Error> {
pub async fn get(uri: &Uri, verify_certs: bool) -> Result<Channel> {
let key = ChannelKey {
uri: uri.clone(),
verify_certs,
Expand Down Expand Up @@ -69,7 +67,7 @@ impl ChannelState {
}
}

async fn connect(uri: Uri, verify_certs: bool) -> Result<Channel, grpc::Error> {
async fn connect(uri: Uri, verify_certs: bool) -> Result<Channel> {
let is_https = uri.scheme() == Some(&Scheme::HTTPS);
let builder = Channel::builder(uri);

Expand Down Expand Up @@ -109,17 +107,9 @@ async fn connect(uri: Uri, verify_certs: bool) -> Result<Channel, grpc::Error> {
.enable_http2()
.wrap_connector(http);

builder
.connect_with_connector(https)
.await
.map_err(anyhow::Error::from)
.map_err(grpc::Error::from)
Ok(builder.connect_with_connector(https).await?)
} else {
builder
.connect()
.await
.map_err(anyhow::Error::from)
.map_err(grpc::Error::from)
Ok(builder.connect().await?)
}
}

Expand Down
9 changes: 3 additions & 6 deletions src/grpc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@ mod codec;
use std::{
mem::take,
str::FromStr,
sync::Arc,
time::{Duration, Instant},
};

use anyhow::Result;
use anyhow::{Error, Result};
use futures::{Stream, StreamExt};
use http::{uri::PathAndQuery, Uri};
use prost_reflect::{DeserializeOptions, DynamicMessage, MessageDescriptor, SerializeOptions};
use tokio::sync::mpsc;
use tokio_stream::wrappers::UnboundedReceiverStream;
use tonic::{client::Grpc, metadata::MetadataMap, transport::Channel, Extensions, Status};

pub type ConnectResult = Result<Client, Error>;
pub type ConnectResult = Result<Client>;

pub enum ResponseResult {
Response(Response),
Expand Down Expand Up @@ -49,8 +48,6 @@ pub struct Call {
request_sender: Option<mpsc::UnboundedSender<Request>>,
}

pub type Error = Arc<anyhow::Error>;

#[derive(Clone, Debug)]
pub struct Client {
grpc: Grpc<Channel>,
Expand Down Expand Up @@ -359,7 +356,7 @@ impl Call {
impl ResponseResult {
fn from_status(mut err: tonic::Status) -> Self {
let metadata = take(err.metadata_mut());
ResponseResult::Error(Arc::new(err.into()), metadata)
ResponseResult::Error(err.into(), metadata)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/protoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub fn load_file(path: &Path) -> Result<DescriptorPool> {
if path.extension() == Some(OsStr::new("proto")) {
bail!("{:?}", err)
} else {
bail!("failed to parse '{}' as either a protobuf source file or encoded file descriptor set: {}", path.display(), err)
bail!("failed to parse file as either a protobuf source file or encoded file descriptor set: {}", err)
}
}
},
Expand Down

0 comments on commit 12a7585

Please sign in to comment.