Skip to main content

systemprompt_models/errors/
service.rs

1//! Application-layer service umbrella error and its conversions into
2//! the public [`crate::api::ApiError`] HTTP shape.
3//!
4//! Copyright (c) systemprompt.io — Business Source License 1.1.
5//! See <https://systemprompt.io> for licensing details.
6
7use systemprompt_traits::RepositoryError;
8
9use crate::api::ApiError;
10
11#[derive(Debug, thiserror::Error)]
12pub enum ServiceError {
13    #[error("repository error: {0}")]
14    Repository(#[from] RepositoryError),
15
16    #[error("validation error: {0}")]
17    Validation(String),
18
19    #[error("business logic error: {0}")]
20    BusinessLogic(String),
21
22    #[error("external service error: {0}")]
23    External(String),
24
25    #[error("not found: {0}")]
26    NotFound(String),
27
28    #[error("conflict: {0}")]
29    Conflict(String),
30
31    #[error("unauthorized: {0}")]
32    Unauthorized(String),
33
34    #[error("forbidden: {0}")]
35    Forbidden(String),
36}
37
38impl From<ServiceError> for ApiError {
39    fn from(err: ServiceError) -> Self {
40        match err {
41            ServiceError::Repository(e) => e.into(),
42            ServiceError::Validation(msg) | ServiceError::BusinessLogic(msg) => {
43                Self::bad_request(msg)
44            },
45            ServiceError::NotFound(msg) => Self::not_found(msg),
46            ServiceError::External(msg) => {
47                Self::internal_error(format!("External service error: {msg}"))
48            },
49            ServiceError::Conflict(msg) => Self::conflict(msg),
50            ServiceError::Unauthorized(msg) => Self::unauthorized(msg),
51            ServiceError::Forbidden(msg) => Self::forbidden(msg),
52        }
53    }
54}
55
56impl From<RepositoryError> for ApiError {
57    fn from(err: RepositoryError) -> Self {
58        match err {
59            RepositoryError::NotFound(msg) => Self::not_found(msg),
60            RepositoryError::InvalidData(msg) | RepositoryError::ConstraintViolation(msg) => {
61                Self::bad_request(msg)
62            },
63            RepositoryError::Database(e) => Self::internal_error(format!("Database error: {e}")),
64            RepositoryError::Serialization(e) => {
65                Self::internal_error(format!("Serialization error: {e}"))
66            },
67            RepositoryError::Internal(msg) => Self::internal_error(format!("Error: {msg}")),
68            _ => Self::internal_error(format!("Repository error: {err}")),
69        }
70    }
71}