Change ErrorCategory to ErrorType

This commit is contained in:
mpostma 2020-05-25 19:11:38 +02:00
parent 30fd24aa47
commit 0e20ac28e5

View File

@ -7,8 +7,22 @@ pub trait ErrorCode: std::error::Error {
fn error_code(&self) -> Code; fn error_code(&self) -> Code;
} }
enum ErrorCategory { enum ErrorType {
None = 0, InternalError,
InvalidRequest,
Authentication,
}
impl fmt::Display for ErrorType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use ErrorType::*;
match self {
InternalError => write!(f, "internal_error"),
InvalidRequest => write!(f, "invalid_request"),
Authentication => write!(f, "authentication"),
}
}
} }
pub enum Code { pub enum Code {
@ -39,154 +53,73 @@ impl Code {
use Code::*; use Code::*;
match self { match self {
BadParameter BadParameter => ErrCode::invalid("bad_parameter", StatusCode::BAD_REQUEST),
| BadRequest BadRequest => ErrCode::invalid("bad_request", StatusCode::BAD_REQUEST),
| CreateIndex CreateIndex => ErrCode::invalid("create_index", StatusCode::BAD_REQUEST),
| InvalidIndexUid InvalidIndexUid => ErrCode::invalid("invalid_index_uid", StatusCode::BAD_REQUEST),
| OpenIndex OpenIndex => ErrCode::invalid("open_index", StatusCode::BAD_REQUEST),
| RetrieveDocument RetrieveDocument => ErrCode::invalid("retrieve_document", StatusCode::BAD_REQUEST),
| SearchDocuments => ErrCode::bad_request(false, false, ErrorCategory::None, 0), SearchDocuments => ErrCode::invalid("search_document", StatusCode::BAD_REQUEST),
DocumentNotFound DocumentNotFound => ErrCode::invalid("document_not_found", StatusCode::BAD_REQUEST),
| IndexNotFound IndexNotFound => ErrCode::invalid("index_not_found", StatusCode::BAD_REQUEST),
| NotFound => ErrCode::not_found(false, false, ErrorCategory::None, 0), NotFound => ErrCode::invalid("not_found", StatusCode::BAD_REQUEST),
InvalidToken InvalidToken => ErrCode::invalid("invalid_token", StatusCode::BAD_REQUEST),
| MissingHeader => ErrCode::unauthorized(false, false, ErrorCategory::None, 0), MissingHeader => ErrCode::invalid("missing_header", StatusCode::BAD_REQUEST),
MissingAuthorizationHeader => ErrCode::forbidden(false, false, ErrorCategory::None, 0), MissingAuthorizationHeader => ErrCode::invalid("missing_authorization_header", StatusCode::BAD_REQUEST),
Internal => ErrCode::internal(false, false, ErrorCategory::None, 0), Internal => ErrCode::invalid("internal", StatusCode::BAD_REQUEST),
Maintenance => ErrCode::service_unavailable(false, false, ErrorCategory::None, 0), Maintenance => ErrCode::invalid("maintenance", StatusCode::BAD_REQUEST),
PayloadTooLarge => ErrCode::payload_too_large(false, false, ErrorCategory::None, 0), PayloadTooLarge => ErrCode::invalid("payload_too_large", StatusCode::BAD_REQUEST),
UnsupportedMediaType => ErrCode::unsupported_media_type(false, false, ErrorCategory::None, 0), UnsupportedMediaType => ErrCode::invalid("unsupported_media_type", StatusCode::BAD_REQUEST),
_ => ErrCode::not_found(false, false, ErrorCategory::None, 0), _ => ErrCode::invalid("other", StatusCode::BAD_REQUEST),
} }
} }
/// return the HTTP status code ascociated with the `Code` /// return the HTTP status code ascociated with the `Code`
pub fn http(&self) -> StatusCode { pub fn http(&self) -> StatusCode {
self.err_code().http_code self.err_code().status_code
} }
/// returns internal error code, in the form: /// return error name, used as error code
/// `EPFCNN` pub fn name(&self) -> String {
/// - E: plain letter "E", to mark an error code, future main introduce W for warning self.err_code().err_name.to_string()
/// - P: scope of the error, 0 for private, 1 for public. Private are error that make no sense
/// reporting to the user, they are internal errors, and there is nothing the user can do about
/// them. they are nonetheless returned, without a message, for assistance purpose.
/// - F: 0 or 1, report if the error is fatal.
/// - C: error category, number in 0-9, the category of the error. Categories are still to be determined, input is required.
/// - NN: The error number, two digits, within C.
pub fn internal(&self) -> String {
let ErrCode { public, fatal, category, code, .. } = self.err_code();
format!("E{}{}{}{}",
public as u16,
fatal as u16,
category as u16,
code)
} }
}
impl fmt::Display for Code { /// return the error type
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub fn r#type(&self) -> String {
self.internal().fmt(f) self.err_code().err_type.to_string()
} }
} }
/// Internal structure providing a convenient way to create error codes /// Internal structure providing a convenient way to create error codes
struct ErrCode { struct ErrCode {
public: bool, status_code: StatusCode,
fatal: bool, err_type: ErrorType,
http_code: StatusCode, err_name: &'static str,
category: ErrorCategory,
code: u16,
} }
impl ErrCode { impl ErrCode {
fn new(
public: bool, fn authentication(err_name: &'static str, status_code: StatusCode) -> ErrCode {
fatal: bool,
http_code: StatusCode,
category: ErrorCategory,
code: u16
) -> ErrCode {
ErrCode { ErrCode {
public, status_code,
fatal, err_name,
http_code, err_type: ErrorType::Authentication,
category,
code,
} }
} }
pub fn internal( fn internal(err_name: &'static str, status_code: StatusCode) -> ErrCode {
public: bool, ErrCode {
fatal: bool, status_code,
category: ErrorCategory, err_name,
code: u16 err_type: ErrorType::InternalError,
) -> ErrCode { }
ErrCode::new(public, fatal, StatusCode::INTERNAL_SERVER_ERROR, category, code)
} }
pub fn bad_request( fn invalid(err_name: &'static str, status_code: StatusCode) -> ErrCode {
public: bool, ErrCode {
fatal: bool, status_code,
category: ErrorCategory, err_name,
code: u16 err_type: ErrorType::InvalidRequest,
) -> ErrCode {
ErrCode::new(public, fatal, StatusCode::BAD_REQUEST, category, code)
} }
pub fn unsupported_media_type(
public: bool,
fatal: bool,
category: ErrorCategory,
code: u16
) -> ErrCode {
ErrCode::new(public, fatal, StatusCode::UNSUPPORTED_MEDIA_TYPE, category, code)
}
pub fn payload_too_large(
public: bool,
fatal: bool,
category: ErrorCategory,
code: u16
) -> ErrCode {
ErrCode::new(public, fatal, StatusCode::PAYLOAD_TOO_LARGE, category, code)
}
pub fn service_unavailable(
public: bool,
fatal: bool,
category: ErrorCategory,
code: u16
) -> ErrCode {
ErrCode::new(public, fatal, StatusCode::SERVICE_UNAVAILABLE, category, code)
}
pub fn forbidden(
public: bool,
fatal: bool,
category: ErrorCategory,
code: u16
) -> ErrCode {
ErrCode::new(public, fatal, StatusCode::FORBIDDEN, category, code)
}
pub fn unauthorized(
public: bool,
fatal: bool,
category: ErrorCategory,
code: u16
) -> ErrCode {
ErrCode::new(public, fatal, StatusCode::UNAUTHORIZED, category, code)
}
pub fn not_found(
public: bool,
fatal: bool,
category: ErrorCategory,
code: u16
) -> ErrCode {
ErrCode::new(public, fatal, StatusCode::NOT_FOUND, category, code)
} }
} }