Skip to main content

loco_rs/model/
mod.rs

1//! # Model Error Handling
2//!
3//! Useful when using `sea_orm` and want to propagate errors
4
5pub mod query;
6use async_trait::async_trait;
7use sea_orm::DatabaseConnection;
8
9use crate::validation::ModelValidationErrors;
10
11#[derive(thiserror::Error, Debug)]
12#[allow(clippy::module_name_repetitions)]
13#[non_exhaustive]
14pub enum ModelError {
15    #[error("Entity already exists")]
16    EntityAlreadyExists,
17
18    #[error("Entity not found")]
19    EntityNotFound,
20
21    #[error(transparent)]
22    Validation(#[from] ModelValidationErrors),
23
24    #[cfg(feature = "auth")]
25    #[error("jwt error")]
26    Jwt(#[from] jsonwebtoken::errors::Error),
27
28    #[error(transparent)]
29    DbErr(#[from] sea_orm::DbErr),
30
31    #[error(transparent)]
32    Any(#[from] Box<dyn std::error::Error + Send + Sync>),
33
34    #[error("{0}")]
35    Message(String),
36}
37
38#[allow(clippy::module_name_repetitions)]
39pub type ModelResult<T, E = ModelError> = std::result::Result<T, E>;
40
41impl ModelError {
42    #[must_use]
43    pub fn wrap(err: impl std::error::Error + Send + Sync + 'static) -> Self {
44        Self::Any(Box::new(err))
45    }
46
47    #[must_use]
48    pub fn to_msg(err: impl std::error::Error + Send + Sync + 'static) -> Self {
49        Self::Message(err.to_string())
50    }
51
52    #[must_use]
53    pub fn msg(s: &str) -> Self {
54        Self::Message(s.to_string())
55    }
56}
57#[async_trait]
58pub trait Authenticable: Clone {
59    async fn find_by_api_key(db: &DatabaseConnection, api_key: &str) -> ModelResult<Self>;
60    async fn find_by_claims_key(db: &DatabaseConnection, claims_key: &str) -> ModelResult<Self>;
61}