From c4e4b7d58599c78aea530b30174b21780b672cc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Bj=C3=A4reholt?= Date: Wed, 12 Dec 2018 22:53:44 +0100 Subject: [PATCH] More detailed error messages and moved away from deprecated error::Error::description (#54) * Replaced deprecated error::Error description with Display * Make OriginNotAllowed and MethodNotAllowed error messages more useful --- src/lib.rs | 69 ++++++++++++++++++++++++------------------------------ 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 76069e4..6327c77 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -598,9 +598,9 @@ pub enum Error { /// The request header `Access-Control-Request-Headers` is required but is missing. MissingRequestHeaders, /// Origin is not allowed to make this request - OriginNotAllowed, + OriginNotAllowed(String), /// Requested method is not allowed - MethodNotAllowed, + MethodNotAllowed(String), /// One or more headers requested are not allowed HeadersNotAllowed, /// Credentials are allowed, but the Origin is set to "*". This is not allowed by W3C @@ -620,8 +620,8 @@ impl Error { fn status(&self) -> Status { match *self { Error::MissingOrigin - | Error::OriginNotAllowed - | Error::MethodNotAllowed + | Error::OriginNotAllowed(_) + | Error::MethodNotAllowed(_) | Error::HeadersNotAllowed => Status::Forbidden, Error::CredentialsWithWildcardOrigin | Error::MissingCorsInRocketState @@ -631,52 +631,45 @@ impl Error { } } -impl error::Error for Error { - fn description(&self) -> &str { - match *self { - Error::MissingOrigin => "The request header `Origin` is required but is missing", - Error::BadOrigin(_) => "The request header `Origin` contains an invalid URL", - Error::MissingRequestMethod => { +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Error::MissingOrigin => write!(f, "The request header `Origin` is required but is missing"), + Error::BadOrigin(_) => write!(f, "The request header `Origin` contains an invalid URL"), + Error::MissingRequestMethod => { write!(f, "The request header `Access-Control-Request-Method` \ - is required but is missing" + is required but is missing") } - Error::BadRequestMethod => { - "The request header `Access-Control-Request-Method` has an invalid value" + Error::BadRequestMethod => { write!(f, + "The request header `Access-Control-Request-Method` has an invalid value") } - Error::MissingRequestHeaders => { + Error::MissingRequestHeaders => { write!(f, "The request header `Access-Control-Request-Headers` \ - is required but is missing" + is required but is missing") } - Error::OriginNotAllowed => "Origin is not allowed to request", - Error::MethodNotAllowed => "Method is not allowed", - Error::HeadersNotAllowed => "Headers are not allowed", - Error::CredentialsWithWildcardOrigin => { + Error::OriginNotAllowed(origin) => write!(f, "Origin '{}' is not allowed to request", &origin), + Error::MethodNotAllowed(method) => write!(f, "Method '{}' is not allowed", &method), + Error::HeadersNotAllowed => write!(f, "Headers are not allowed"), + Error::CredentialsWithWildcardOrigin => { write!(f, "Credentials are allowed, but the Origin is set to \"*\". \ - This is not allowed by W3C" + This is not allowed by W3C") } - Error::MissingCorsInRocketState => { - "A CORS Request Guard was used, but no CORS Options was available in Rocket's state" + Error::MissingCorsInRocketState => { write!(f, + "A CORS Request Guard was used, but no CORS Options was available in Rocket's state") } - Error::MissingInjectedHeader => { + Error::MissingInjectedHeader => write!(f, "The `on_response` handler of Fairing could not find the injected header from the \ - Request. Either some other fairing has removed it, or this is a bug." - } - } - } - - fn cause(&self) -> Option<&dyn error::Error> { - match *self { - Error::BadOrigin(ref e) => Some(e), - _ => Some(self), + Request. Either some other fairing has removed it, or this is a bug.") } } } -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + +impl error::Error for Error { + fn cause(&self) -> Option<&dyn error::Error> { match *self { - Error::BadOrigin(ref e) => fmt::Display::fmt(e, f), - _ => write!(f, "{}", error::Error::description(self)), + Error::BadOrigin(ref e) => Some(e), + _ => Some(self), } } } @@ -1584,7 +1577,7 @@ fn validate_origin( AllOrSome::Some(ref allowed_origins) => allowed_origins .get(origin) .and_then(|_| Some(())) - .ok_or_else(|| Error::OriginNotAllowed), + .ok_or_else(|| Error::OriginNotAllowed(origin.to_string())), } } @@ -1595,7 +1588,7 @@ fn validate_allowed_method( ) -> Result<(), Error> { let &AccessControlRequestMethod(ref request_method) = method; if !allowed_methods.iter().any(|m| m == request_method) { - Err(Error::MethodNotAllowed)? + Err(Error::MethodNotAllowed(method.0.to_string()))? } // TODO: Subset to route? Or just the method requested for?