Skip to content

Commit 3644c52

Browse files
committed
Better API error handling for Agent
1 parent 67ded1a commit 3644c52

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

agent/src/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// https://www.tldrlegal.com/l/mpl-2.0>. This file may not be copied,
55
// modified, or distributed except according to those terms.
66

7+
use error_chain::ChainedError;
78
use futures::Future;
89
use intecture_api;
910
use std::{convert, error, io};
@@ -16,8 +17,7 @@ error_chain! {
1617

1718
impl convert::From<Error> for io::Error {
1819
fn from(e: Error) -> io::Error {
19-
// @todo Return whole error chain
20-
io::Error::new(io::ErrorKind::Other, e.description())
20+
io::Error::new(io::ErrorKind::Other, format!("{}", e.display_chain()))
2121
}
2222
}
2323

agent/src/main.rs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ extern crate toml;
1818

1919
mod errors;
2020

21+
use error_chain::ChainedError;
2122
use errors::*;
2223
use futures::{future, Future};
2324
use intecture_api::host::local::Local;
2425
use intecture_api::host::remote::{JsonLineProto, LineMessage};
25-
use intecture_api::remote::{Executable, Request};
26+
use intecture_api::remote::{Executable, Request, ResponseResult};
2627
use std::fs::File;
2728
use std::io::{self, Read};
2829
use std::net::SocketAddr;
@@ -49,9 +50,9 @@ impl Service for Api {
4950
Message::WithoutBody(req) => req,
5051
};
5152

52-
let request: Request = match serde_json::from_value(req).chain_err(|| "Received invalid Request") {
53+
let request: Request = match serde_json::from_value(req).chain_err(|| "Could not deserialize Request") {
5354
Ok(r) => r,
54-
Err(e) => return Box::new(future::err(e))
55+
Err(e) => return Box::new(future::ok(error_to_msg(e))),
5556
};
5657

5758
// XXX Danger zone! If we're running multiple threads, this `unwrap()`
@@ -62,14 +63,19 @@ impl Service for Api {
6263
let handle = self.remote.handle().unwrap();
6364
Box::new(request.exec(&self.host, &handle)
6465
.chain_err(|| "Failed to execute Request")
65-
.and_then(|mut msg| {
66-
let body = msg.take_body();
67-
match serde_json::to_value(msg.into_inner()).chain_err(|| "Could not serialize result") {
68-
Ok(v) => match body {
69-
Some(b) => future::ok(Message::WithBody(v, b)),
70-
None => future::ok(Message::WithoutBody(v)),
66+
.then(|req| {
67+
match req {
68+
Ok(mut msg) => {
69+
let body = msg.take_body();
70+
match serde_json::to_value(msg.into_inner()).chain_err(|| "Could not serialize Result") {
71+
Ok(v) => match body {
72+
Some(b) => future::ok(Message::WithBody(v, b)),
73+
None => future::ok(Message::WithoutBody(v)),
74+
},
75+
Err(e) => future::ok(error_to_msg(e)),
76+
}
7177
},
72-
Err(e) => future::err(e),
78+
Err(e) => future::ok(error_to_msg(e)),
7379
}
7480
}))
7581
}
@@ -143,3 +149,12 @@ quick_main!(|| -> Result<()> {
143149
});
144150
Ok(())
145151
});
152+
153+
fn error_to_msg(e: Error) -> LineMessage {
154+
let response = ResponseResult::Err(format!("{}", e.display_chain()));
155+
// If we can't serialize this, we can't serialize anything, so
156+
// panicking is appropriate.
157+
let value = serde_json::to_value(response)
158+
.expect("Cannot serialize ResponseResult::Err. This is bad...");
159+
Message::WithoutBody(value)
160+
}

0 commit comments

Comments
 (0)