fish_lib/game/errors/
repository.rs1use 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}