fish_lib/game/errors/
repository.rs

1use crate::game::errors::database::GameDatabaseError;
2use diesel::result::DatabaseErrorKind;
3use std::error::Error;
4use thiserror::Error;
5
6#[derive(Error, Debug)]
7pub enum GameRepositoryError {
8    #[error("Database error: {0}")]
9    Database(#[from] GameDatabaseError),
10    #[error("Unexpected error: {msg}")]
11    Unexpected {
12        msg: String,
13        #[source]
14        source: Box<dyn std::error::Error>,
15    },
16}
17
18impl GameRepositoryError {
19    pub fn database(error: GameDatabaseError) -> Self {
20        Self::Database(error)
21    }
22
23    pub fn unexpected(error: Box<dyn std::error::Error>) -> Self {
24        Self::Unexpected {
25            msg: error.to_string(),
26            source: error,
27        }
28    }
29
30    pub fn is_database_error(&self) -> bool {
31        matches!(self, Self::Database(_))
32    }
33
34    pub fn get_database_error(&self) -> Option<&GameDatabaseError> {
35        match self {
36            Self::Database(database_error) => Some(database_error),
37            _ => None,
38        }
39    }
40}
41
42impl From<Box<dyn Error>> for GameRepositoryError {
43    fn from(value: Box<dyn Error>) -> Self {
44        Self::unexpected(value)
45    }
46}
47
48impl From<diesel::result::Error> for GameRepositoryError {
49    fn from(error: diesel::result::Error) -> Self {
50        match error {
51            diesel::result::Error::DatabaseError(kind, info) => match kind {
52                DatabaseErrorKind::ForeignKeyViolation => {
53                    Self::database(GameDatabaseError::foreign_key_violation(info.message()))
54                }
55                DatabaseErrorKind::UniqueViolation => Self::database(
56                    GameDatabaseError::unique_constraint_violation(info.message()),
57                ),
58                _ => Self::database(GameDatabaseError::other(info.message())),
59            },
60            diesel::result::Error::NotFound => Self::database(GameDatabaseError::not_found()),
61            _ => Self::unexpected(error.into()),
62        }
63    }
64}