diff options
author | Alex Auvolat <alex@adnab.me> | 2022-05-13 13:51:34 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2022-05-13 13:51:34 +0200 |
commit | 983037d965fdcdf089b09fa90fac31501defae9e (patch) | |
tree | 716efccaf76d5e165183d550cfc4bcf894482c7d /src/api/error.rs | |
parent | e4e1f8f0d60545d81c1082ca5f0194962a4a4f79 (diff) | |
download | garage-983037d965fdcdf089b09fa90fac31501defae9e.tar.gz garage-983037d965fdcdf089b09fa90fac31501defae9e.zip |
Possibility of different error types for different APIs
Diffstat (limited to 'src/api/error.rs')
-rw-r--r-- | src/api/error.rs | 85 |
1 files changed, 44 insertions, 41 deletions
diff --git a/src/api/error.rs b/src/api/error.rs index f111c801..5c33d763 100644 --- a/src/api/error.rs +++ b/src/api/error.rs @@ -2,11 +2,12 @@ use std::convert::TryInto; use err_derive::Error; use hyper::header::HeaderValue; -use hyper::{HeaderMap, StatusCode}; +use hyper::{Body, HeaderMap, StatusCode}; use garage_model::helper::error::Error as HelperError; use garage_util::error::Error as GarageError; +use crate::generic_server::ApiError; use crate::s3::xml as s3_xml; /// Errors of this crate @@ -142,28 +143,6 @@ impl From<multer::Error> for Error { } impl Error { - /// Get the HTTP status code that best represents the meaning of the error for the client - pub fn http_status_code(&self) -> StatusCode { - match self { - Error::NoSuchKey | Error::NoSuchBucket | Error::NoSuchUpload => StatusCode::NOT_FOUND, - Error::BucketNotEmpty | Error::BucketAlreadyExists => StatusCode::CONFLICT, - Error::PreconditionFailed => StatusCode::PRECONDITION_FAILED, - Error::Forbidden(_) => StatusCode::FORBIDDEN, - Error::NotAcceptable(_) => StatusCode::NOT_ACCEPTABLE, - Error::InternalError( - GarageError::Timeout - | GarageError::RemoteError(_) - | GarageError::Quorum(_, _, _, _), - ) => StatusCode::SERVICE_UNAVAILABLE, - Error::InternalError(_) | Error::Hyper(_) | Error::Http(_) => { - StatusCode::INTERNAL_SERVER_ERROR - } - Error::InvalidRange(_) => StatusCode::RANGE_NOT_SATISFIABLE, - Error::NotImplemented(_) => StatusCode::NOT_IMPLEMENTED, - _ => StatusCode::BAD_REQUEST, - } - } - pub fn aws_code(&self) -> &'static str { match self { Error::NoSuchKey => "NoSuchKey", @@ -187,27 +166,32 @@ impl Error { _ => "InvalidRequest", } } +} - pub fn aws_xml(&self, garage_region: &str, path: &str) -> String { - let error = s3_xml::Error { - code: s3_xml::Value(self.aws_code().to_string()), - message: s3_xml::Value(format!("{}", self)), - resource: Some(s3_xml::Value(path.to_string())), - region: Some(s3_xml::Value(garage_region.to_string())), - }; - s3_xml::to_xml_with_header(&error).unwrap_or_else(|_| { - r#" -<?xml version="1.0" encoding="UTF-8"?> -<Error> - <Code>InternalError</Code> - <Message>XML encoding of error failed</Message> -</Error> - "# - .into() - }) +impl ApiError for Error { + /// Get the HTTP status code that best represents the meaning of the error for the client + fn http_status_code(&self) -> StatusCode { + match self { + Error::NoSuchKey | Error::NoSuchBucket | Error::NoSuchUpload => StatusCode::NOT_FOUND, + Error::BucketNotEmpty | Error::BucketAlreadyExists => StatusCode::CONFLICT, + Error::PreconditionFailed => StatusCode::PRECONDITION_FAILED, + Error::Forbidden(_) => StatusCode::FORBIDDEN, + Error::NotAcceptable(_) => StatusCode::NOT_ACCEPTABLE, + Error::InternalError( + GarageError::Timeout + | GarageError::RemoteError(_) + | GarageError::Quorum(_, _, _, _), + ) => StatusCode::SERVICE_UNAVAILABLE, + Error::InternalError(_) | Error::Hyper(_) | Error::Http(_) => { + StatusCode::INTERNAL_SERVER_ERROR + } + Error::InvalidRange(_) => StatusCode::RANGE_NOT_SATISFIABLE, + Error::NotImplemented(_) => StatusCode::NOT_IMPLEMENTED, + _ => StatusCode::BAD_REQUEST, + } } - pub fn add_headers(&self, header_map: &mut HeaderMap<HeaderValue>) { + fn add_http_headers(&self, header_map: &mut HeaderMap<HeaderValue>) { use hyper::header; #[allow(clippy::single_match)] match self { @@ -222,6 +206,25 @@ impl Error { _ => (), } } + + fn http_body(&self, garage_region: &str, path: &str) -> Body { + let error = s3_xml::Error { + code: s3_xml::Value(self.aws_code().to_string()), + message: s3_xml::Value(format!("{}", self)), + resource: Some(s3_xml::Value(path.to_string())), + region: Some(s3_xml::Value(garage_region.to_string())), + }; + Body::from(s3_xml::to_xml_with_header(&error).unwrap_or_else(|_| { + r#" +<?xml version="1.0" encoding="UTF-8"?> +<Error> + <Code>InternalError</Code> + <Message>XML encoding of error failed</Message> +</Error> + "# + .into() + })) + } } /// Trait to map error to the Bad Request error code |