use http::StatusCode;
use soaprs_core::{SoapError, SoapErrorKind};
pub const fn default_error_status(error: &SoapError) -> StatusCode {
match error.kind() {
SoapErrorKind::NotFound => StatusCode::NOT_FOUND,
SoapErrorKind::Validation | SoapErrorKind::Domain => StatusCode::UNPROCESSABLE_ENTITY,
SoapErrorKind::Conflict => StatusCode::CONFLICT,
SoapErrorKind::Unauthorized => StatusCode::UNAUTHORIZED,
SoapErrorKind::Forbidden => StatusCode::FORBIDDEN,
SoapErrorKind::Unsupported => StatusCode::NOT_IMPLEMENTED,
SoapErrorKind::Timeout => StatusCode::GATEWAY_TIMEOUT,
SoapErrorKind::Unavailable => StatusCode::SERVICE_UNAVAILABLE,
SoapErrorKind::Infrastructure => StatusCode::INTERNAL_SERVER_ERROR,
}
}
#[cfg(test)]
mod tests {
use http::StatusCode;
use soaprs_core::SoapError;
use super::default_error_status;
#[test]
fn distinguishes_authentication_and_authorization() {
assert_eq!(
default_error_status(&SoapError::unauthorized()),
StatusCode::UNAUTHORIZED
);
assert_eq!(
default_error_status(&SoapError::forbidden()),
StatusCode::FORBIDDEN
);
}
#[test]
fn maps_stable_error_categories_to_default_statuses() {
let cases = [
(SoapError::not_found("user"), StatusCode::NOT_FOUND),
(
SoapError::validation("invalid email"),
StatusCode::UNPROCESSABLE_ENTITY,
),
(
SoapError::domain("account is closed"),
StatusCode::UNPROCESSABLE_ENTITY,
),
(SoapError::conflict("email exists"), StatusCode::CONFLICT),
(
SoapError::unsupported("full-text search"),
StatusCode::NOT_IMPLEMENTED,
),
(
SoapError::timeout("database query"),
StatusCode::GATEWAY_TIMEOUT,
),
(
SoapError::unavailable("database"),
StatusCode::SERVICE_UNAVAILABLE,
),
(
SoapError::infrastructure("database operation"),
StatusCode::INTERNAL_SERVER_ERROR,
),
];
for (error, expected) in cases {
assert_eq!(default_error_status(&error), expected);
}
}
}