systemprompt-models 0.6.0

Foundation data models for systemprompt.io AI governance infrastructure. Shared DTOs, config, and domain types consumed by every layer of the MCP governance pipeline.
Documentation
//! Application-layer service umbrella error and its conversions into
//! the public [`crate::api::ApiError`] HTTP shape.

use systemprompt_traits::RepositoryError;

use crate::api::ApiError;

#[derive(Debug, thiserror::Error)]
pub enum ServiceError {
    #[error("repository error: {0}")]
    Repository(#[from] RepositoryError),

    #[error("validation error: {0}")]
    Validation(String),

    #[error("business logic error: {0}")]
    BusinessLogic(String),

    #[error("external service error: {0}")]
    External(String),

    #[error("not found: {0}")]
    NotFound(String),

    #[error("conflict: {0}")]
    Conflict(String),

    #[error("unauthorized: {0}")]
    Unauthorized(String),

    #[error("forbidden: {0}")]
    Forbidden(String),
}

impl From<ServiceError> for ApiError {
    fn from(err: ServiceError) -> Self {
        match err {
            ServiceError::Repository(e) => e.into(),
            ServiceError::Validation(msg) | ServiceError::BusinessLogic(msg) => {
                Self::bad_request(msg)
            },
            ServiceError::NotFound(msg) => Self::not_found(msg),
            ServiceError::External(msg) => {
                Self::internal_error(format!("External service error: {msg}"))
            },
            ServiceError::Conflict(msg) => Self::conflict(msg),
            ServiceError::Unauthorized(msg) => Self::unauthorized(msg),
            ServiceError::Forbidden(msg) => Self::forbidden(msg),
        }
    }
}

impl From<RepositoryError> for ApiError {
    fn from(err: RepositoryError) -> Self {
        match err {
            RepositoryError::NotFound(msg) => Self::not_found(msg),
            RepositoryError::InvalidData(msg) | RepositoryError::ConstraintViolation(msg) => {
                Self::bad_request(msg)
            },
            RepositoryError::Database(e) => Self::internal_error(format!("Database error: {e}")),
            RepositoryError::Serialization(e) => {
                Self::internal_error(format!("Serialization error: {e}"))
            },
            RepositoryError::Other(e) => Self::internal_error(format!("Error: {e}")),
            _ => Self::internal_error(format!("Repository error: {err}")),
        }
    }
}