diff options
author | Tim Martin <tim.martin@metaswitch.com> | 2017-04-25 13:47:45 +0100 |
---|---|---|
committer | Tim Martin <tim.martin@metaswitch.com> | 2017-04-25 13:49:57 +0100 |
commit | 43565880b6d1f3aa0fe9a71384ada8b83227687e (patch) | |
tree | 05d984045ee956cfe663d2351b4eab3fbf27e47d /src/transport.rs | |
parent | f219ff165a5fb39b400c2b7649efc5c1aa89ca01 (diff) |
The transport extracts a message from the response JSON if possible
Diffstat (limited to 'src/transport.rs')
-rw-r--r-- | src/transport.rs | 33 |
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 + } +} |