Handle errors

This commit is contained in:
Curtis McEnroe 2015-11-28 18:07:01 -05:00
parent 75d309ad0c
commit 91dd81690d
2 changed files with 36 additions and 11 deletions

View File

@ -5,7 +5,8 @@ use hyper::{self, header, mime};
use rustc_serialize::json;
use url::{Url, form_urlencoded};
use super::{Error, Result, Token};
use super::Token;
use super::error::{Error, Result, OAuth2Error, OAuth2ErrorCode};
/// OAuth 2.0 client.
pub struct Client {
@ -40,6 +41,32 @@ impl Into<Token> for TokenResponse {
}
}
#[derive(RustcDecodable)]
struct ErrorResponse {
error: String,
error_description: Option<String>,
error_uri: Option<String>,
}
impl Into<OAuth2Error> for ErrorResponse {
fn into(self) -> OAuth2Error {
let code = match &self.error[..] {
"invalid_request" => OAuth2ErrorCode::InvalidRequest,
"invalid_client" => OAuth2ErrorCode::InvalidClient,
"invalid_grant" => OAuth2ErrorCode::InvalidGrant,
"unauthorized_client" => OAuth2ErrorCode::UnauthorizedClient,
"unsupported_grant_type" => OAuth2ErrorCode::UnsupportedGrantType,
"invalid_scope" => OAuth2ErrorCode::InvalidScope,
_ => OAuth2ErrorCode::Unrecognized(self.error),
};
OAuth2Error {
code: code,
description: self.error_description,
uri: self.error_uri,
}
}
}
macro_rules! site_constructors {
(
$(
@ -161,14 +188,15 @@ impl Client {
.body(&body_str);
let mut response = try!(request.send());
let mut json = String::new();
try!(response.read_to_string(&mut json));
let mut body = String::new();
try!(response.read_to_string(&mut body));
if response.status != hyper::Ok {
return Err(Error::Todo);
let token = json::decode::<TokenResponse>(&body);
if let Ok(token) = token {
return Ok(token.into());
}
let token: TokenResponse = try!(json::decode(&json));
Ok(token.into())
let error: ErrorResponse = try!(json::decode(&body));
Err(Error::OAuth2(error.into()))
}
}

View File

@ -13,6 +13,7 @@ pub enum OAuth2ErrorCode {
UnauthorizedClient,
UnsupportedGrantType,
InvalidScope,
Unrecognized(String),
}
/// OAuth 2.0 error.
@ -52,7 +53,6 @@ pub enum Error {
Hyper(hyper::Error),
Json(json::DecoderError),
OAuth2(OAuth2Error),
Todo,
}
/// Result type returned from authentication flow methods.
@ -66,7 +66,6 @@ impl fmt::Display for Error {
Error::Hyper(ref err) => write!(f, "{}", err),
Error::Json(ref err) => write!(f, "{}", err),
Error::OAuth2(ref err) => write!(f, "{}", err),
Error::Todo => write!(f, "Not implemented!"),
}
}
}
@ -79,7 +78,6 @@ impl error::Error for Error {
Error::Hyper(_) => "OAuth2 Hyper error",
Error::Json(_) => "OAuth2 JSON error",
Error::OAuth2(_) => "OAuth2 API error",
Error::Todo => "OAuth2 not implemented error",
}
}
@ -90,7 +88,6 @@ impl error::Error for Error {
Error::Hyper(ref err) => Some(err),
Error::Json(ref err) => Some(err),
Error::OAuth2(ref err) => Some(err),
_ => None,
}
}
}