29b68f7
ZhenYi
feat(members): add members navigation and roster components with role filtering and search functionality
29b68f7
use std::fmt;
#[derive(Debug)]
pub enum UserError {
BadRequest(String),
Unauthorized,
Forbidden,
NotFound,
Conflict(String),
Internal(String),
}
impl fmt::Display for UserError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BadRequest(message) => write!(f, "{message}"),
Self::Unauthorized => write!(f, "unauthorized"),
Self::Forbidden => write!(f, "forbidden"),
Self::NotFound => write!(f, "not found"),
Self::Conflict(message) => write!(f, "{message}"),
Self::Internal(message) => write!(f, "{message}"),
}
}
}
impl std::error::Error for UserError {}
api::access_error_conversion!(UserError, BadRequest);
auth::auth_error_conversion!(UserError);
api::db_error_conversions!(UserError);
storage::storage_error_conversion!(UserError);
cache::redis_error_conversion!(UserError);
api::json_payload_conversion!(UserError);
api::page_error_conversion!(UserError, BadRequest);
api::api_error! {
log: "user",
pub enum ApiError {
BadRequest(400, "request failed validation"),
Unauthorized(401, "authentication required"),
Forbidden(403, "operation not allowed"),
NotFound(404, "resource not found"),
Conflict(409, "resource conflict"),
RateLimited(429, "rate limit exceeded"),
PreconditionFailed(412, "precondition failed"),
Unavailable(503, "service unavailable"),
Internal(500, "internal server error"),
}
}
impl From<UserError> for ApiError {
fn from(error: UserError) -> Self {
match error {
UserError::BadRequest(msg) => Self::bad_request(msg),
UserError::Unauthorized => Self::unauthorized(),
UserError::Forbidden => Self::forbidden(),
UserError::NotFound => Self::not_found("user resource not found"),
UserError::Conflict(msg) => Self::conflict(msg),
UserError::Internal(message) => Self::internal(message),
}
}
}
impl From<auth::AuthError> for ApiError {
fn from(error: auth::AuthError) -> Self {
let status = error.status_code().as_u16();
if error.is_internal() {
tracing::warn!(%error, "user SSH key handler failed");
}
let mut response = api::rest::AppResponseData::err(i32::from(status), error.message())
.with_error_code(error.code());
if let auth::AuthError::RateLimited { retry_after_secs } = &error {
response = response.with_retry_after(*retry_after_secs);
}
Self::build(status, response)
}
}