MeiliSearch/meilisearch-error/src/lib.rs

126 lines
3.8 KiB
Rust
Raw Normal View History

2020-05-19 18:13:02 +02:00
#![allow(dead_code)]
use std::fmt;
use actix_http::http::StatusCode;
pub trait ErrorCode: std::error::Error {
fn error_code(&self) -> Code;
}
2020-05-25 19:11:38 +02:00
enum ErrorType {
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"),
}
}
2020-05-19 18:13:02 +02:00
}
pub enum Code {
2020-05-22 18:04:23 +02:00
BadParameter,
BadRequest,
CreateIndex,
DocumentNotFound,
IndexNotFound,
Internal,
InvalidIndexUid,
InvalidToken,
Maintenance,
MissingAuthorizationHeader,
MissingHeader,
NotFound,
OpenIndex,
RetrieveDocument,
SearchDocuments,
PayloadTooLarge,
UnsupportedMediaType,
2020-05-19 18:13:02 +02:00
Other,
}
2020-05-22 18:04:23 +02:00
impl Code {
/// ascociate a `Code` variant to the actual ErrCode
fn err_code(&self) -> ErrCode {
use Code::*;
match self {
2020-05-25 19:11:38 +02:00
BadParameter => ErrCode::invalid("bad_parameter", StatusCode::BAD_REQUEST),
BadRequest => ErrCode::invalid("bad_request", StatusCode::BAD_REQUEST),
CreateIndex => ErrCode::invalid("create_index", StatusCode::BAD_REQUEST),
InvalidIndexUid => ErrCode::invalid("invalid_index_uid", StatusCode::BAD_REQUEST),
OpenIndex => ErrCode::invalid("open_index", StatusCode::BAD_REQUEST),
RetrieveDocument => ErrCode::invalid("retrieve_document", StatusCode::BAD_REQUEST),
SearchDocuments => ErrCode::invalid("search_document", StatusCode::BAD_REQUEST),
DocumentNotFound => ErrCode::invalid("document_not_found", StatusCode::BAD_REQUEST),
IndexNotFound => ErrCode::invalid("index_not_found", StatusCode::BAD_REQUEST),
NotFound => ErrCode::invalid("not_found", StatusCode::BAD_REQUEST),
InvalidToken => ErrCode::invalid("invalid_token", StatusCode::BAD_REQUEST),
MissingHeader => ErrCode::invalid("missing_header", StatusCode::BAD_REQUEST),
MissingAuthorizationHeader => ErrCode::invalid("missing_authorization_header", StatusCode::BAD_REQUEST),
Internal => ErrCode::invalid("internal", StatusCode::BAD_REQUEST),
Maintenance => ErrCode::invalid("maintenance", StatusCode::BAD_REQUEST),
PayloadTooLarge => ErrCode::invalid("payload_too_large", StatusCode::BAD_REQUEST),
UnsupportedMediaType => ErrCode::invalid("unsupported_media_type", StatusCode::BAD_REQUEST),
_ => ErrCode::invalid("other", StatusCode::BAD_REQUEST),
2020-05-22 18:04:23 +02:00
}
}
/// return the HTTP status code ascociated with the `Code`
pub fn http(&self) -> StatusCode {
2020-05-25 19:11:38 +02:00
self.err_code().status_code
2020-05-22 18:04:23 +02:00
}
2020-05-25 19:11:38 +02:00
/// return error name, used as error code
pub fn name(&self) -> String {
self.err_code().err_name.to_string()
2020-05-22 18:04:23 +02:00
}
2020-05-25 19:11:38 +02:00
/// return the error type
pub fn r#type(&self) -> String {
self.err_code().err_type.to_string()
2020-05-19 18:13:02 +02:00
}
}
/// Internal structure providing a convenient way to create error codes
struct ErrCode {
2020-05-25 19:11:38 +02:00
status_code: StatusCode,
err_type: ErrorType,
err_name: &'static str,
2020-05-19 18:13:02 +02:00
}
impl ErrCode {
2020-05-25 19:11:38 +02:00
fn authentication(err_name: &'static str, status_code: StatusCode) -> ErrCode {
2020-05-19 18:13:02 +02:00
ErrCode {
2020-05-25 19:11:38 +02:00
status_code,
err_name,
err_type: ErrorType::Authentication,
2020-05-19 18:13:02 +02:00
}
}
2020-05-25 19:11:38 +02:00
fn internal(err_name: &'static str, status_code: StatusCode) -> ErrCode {
ErrCode {
status_code,
err_name,
err_type: ErrorType::InternalError,
}
2020-05-22 18:04:23 +02:00
}
2020-05-19 18:13:02 +02:00
2020-05-25 19:11:38 +02:00
fn invalid(err_name: &'static str, status_code: StatusCode) -> ErrCode {
ErrCode {
status_code,
err_name,
err_type: ErrorType::InvalidRequest,
}
2020-05-19 18:13:02 +02:00
}
}