From 7dc9972445593f592f369759b9839a3dedf8d12c Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Tue, 14 Apr 2015 10:28:59 +0200 Subject: [PATCH] feat(API): Display + Error traits for Error struct * improved documentation about error handling, it's less verbose yet explains what you can do. Fixes #56 --- src/mako/api/lib/mbuild.mako | 20 ++++++++-------- src/mako/cli/main.rs.mako | 2 +- src/rust/api/cmn.rs | 44 ++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/mako/api/lib/mbuild.mako b/src/mako/api/lib/mbuild.mako index 49c16d05798..f48a775b801 100644 --- a/src/mako/api/lib/mbuild.mako +++ b/src/mako/api/lib/mbuild.mako @@ -361,16 +361,18 @@ ${'.' + action_name | indent_by(13)}(${action_args}); match result { Err(e) => match e { - Error::HttpError(err) => println!("HTTPERROR: {:?}", err), - Error::MissingAPIKey => println!("Auth: Missing API Key - used if there are no scopes"), - Error::MissingToken => println!("OAuth2: Missing Token"), - Error::Cancelled => println!("Operation canceled by user"), - Error::UploadSizeLimitExceeded(size, max_size) => println!("Upload size too big: {} of {}", size, max_size), - Error::Failure(_) => println!("General Failure (hyper::client::Response doesn't print)"), - Error::FieldClash(clashed_field) => println!("You added custom parameter which is part of builder: {:?}", clashed_field), - Error::JsonDecodeError(err) => println!("Couldn't understand server reply - maybe API needs update: {:?}", err), + // The Error enum provides details about what exactly happened. + // You can also just use its `Debug`, `Display` or `Error` traits + Error::HttpError(_) + |Error::MissingAPIKey + |Error::MissingToken + |Error::Cancelled + |Error::UploadSizeLimitExceeded(_, _) + |Error::Failure(_) + |Error::FieldClash(_) + |Error::JsonDecodeError(_) => println!("{}", e), }, - Ok(_) => println!("Success (value doesn't print)"), + Ok(res) => println!("Success: {:?}", res), } % endif diff --git a/src/mako/cli/main.rs.mako b/src/mako/cli/main.rs.mako index 96d6a1eb26c..5b4837fe540 100644 --- a/src/mako/cli/main.rs.mako +++ b/src/mako/cli/main.rs.mako @@ -36,7 +36,7 @@ fn main() { }, Ok(engine) => { if let Some(err) = engine.doit() { - write!(io::stderr(), "TODO: display {:?}", err).ok(); + write!(io::stderr(), "{}", err).ok(); env::set_exit_status(1); } } diff --git a/src/rust/api/cmn.rs b/src/rust/api/cmn.rs index 8a872adc32a..6913284b82d 100644 --- a/src/rust/api/cmn.rs +++ b/src/rust/api/cmn.rs @@ -2,6 +2,7 @@ use std::io::{self, Read, Seek, Cursor, Write, SeekFrom}; use std; use std::fmt::{self, Display}; use std::str::FromStr; +use std::error; use std::thread::sleep_ms; use mime::{Mime, TopLevel, SubLevel, Attr, Value}; @@ -245,6 +246,49 @@ pub enum Error { Failure(hyper::client::Response), } + +impl Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Error::HttpError(ref err) => err.fmt(f), + Error::UploadSizeLimitExceeded(ref resource_size, ref max_size) => + writeln!(f, "The media size {} exceeds the maximum allowed upload size of {}" + , resource_size, max_size), + Error::MissingAPIKey => { + writeln!(f, "The application's API key was not found in the configuration").ok(); + writeln!(f, "It is used as there are no Scopes defined for this method.") + }, + Error::MissingToken => + writeln!(f, "Didn't obtain authentication token from authenticator"), + Error::Cancelled => + writeln!(f, "Operation cancelled by delegate"), + Error::FieldClash(field) => + writeln!(f, "The custom parameter '{}' is already provided natively by the CallBuilder.", field), + Error::JsonDecodeError(ref err) => err.fmt(f), + Error::Failure(ref response) => + writeln!(f, "Http status indicates failure: {:?}", response), + } + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + match *self { + Error::HttpError(ref err) => err.description(), + Error::JsonDecodeError(ref err) => err.description(), + _ => "NO DESCRIPTION POSSIBLE - use `Display.fmt()` instead" + } + } + + fn cause(&self) -> Option<&error::Error> { + match *self { + Error::HttpError(ref err) => err.cause(), + Error::JsonDecodeError(ref err) => err.cause(), + _ => None + } + } +} + /// A universal result type used as return for all calls. pub type Result = std::result::Result;