summaryrefslogtreecommitdiffstats
path: root/src/transport.rs
diff options
context:
space:
mode:
authorTim Martin <tim.martin@metaswitch.com>2017-04-25 13:47:45 +0100
committerTim Martin <tim.martin@metaswitch.com>2017-04-25 13:49:57 +0100
commit43565880b6d1f3aa0fe9a71384ada8b83227687e (patch)
tree05d984045ee956cfe663d2351b4eab3fbf27e47d /src/transport.rs
parentf219ff165a5fb39b400c2b7649efc5c1aa89ca01 (diff)
The transport extracts a message from the response JSON if possible
Diffstat (limited to 'src/transport.rs')
-rw-r--r--src/transport.rs33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/transport.rs b/src/transport.rs
index 05ac125..5762e59 100644
--- a/src/transport.rs
+++ b/src/transport.rs
@@ -4,6 +4,7 @@ extern crate hyper;
use hyper::Client;
use hyper::client::Body;
+use hyper::client::response::Response;
use hyper::header;
use hyper::mime;
use self::super::{Error, Result};
@@ -14,6 +15,7 @@ use hyper::method::Method;
use std::fmt;
use std::io::Read;
use hyperlocal::DomainUrl;
+use rustc_serialize::json;
pub fn tar() -> ContentType {
ContentType(mime::Mime(mime::TopLevel::Application,
@@ -85,7 +87,7 @@ impl Transport {
Some((b, c)) => req.header(c).body(b),
_ => req,
};
- let res = try!(embodied.send());
+ let mut res = try!(embodied.send());
match res.status {
StatusCode::Ok | StatusCode::Created | StatusCode::SwitchingProtocols => {
Ok(Box::new(res))
@@ -95,34 +97,53 @@ impl Transport {
StatusCode::BadRequest => {
Err(Error::Fault {
code: res.status,
- message: "bad parameter".to_owned(),
+ message: get_error_message(&mut res).unwrap_or("bad parameter".to_owned()),
})
}
StatusCode::NotFound => {
Err(Error::Fault {
code: res.status,
- message: "not found".to_owned(),
+ message: get_error_message(&mut res).unwrap_or("not found".to_owned()),
})
}
StatusCode::NotAcceptable => {
Err(Error::Fault {
code: res.status,
- message: "not acceptable".to_owned(),
+ message: get_error_message(&mut res).unwrap_or("not acceptable".to_owned()),
})
}
StatusCode::Conflict => {
Err(Error::Fault {
code: res.status,
- message: "conflict found".to_owned(),
+ message: get_error_message(&mut res).unwrap_or("conflict found".to_owned()),
})
}
StatusCode::InternalServerError => {
Err(Error::Fault {
code: res.status,
- message: "internal server error".to_owned(),
+ message: get_error_message(&mut res).unwrap_or("internal server error".to_owned())
})
}
_ => unreachable!(),
}
}
}
+
+/// Extract the error message content from an HTTP response that
+/// contains a Docker JSON error structure.
+fn get_error_message(res: &mut Response) -> Option<String> {
+ let mut output = String::new();
+ if res.read_to_string(&mut output).is_ok() {
+ let json_response = json::Json::from_str(output.as_str()).ok();
+ let message = json_response.as_ref()
+ .and_then(|x| x.as_object())
+ .and_then(|x| x.get("message"))
+ .and_then(|x| x.as_string())
+ .map(|x| x.to_owned());
+
+ message
+ }
+ else {
+ None
+ }
+}