Skip to main content

nestrs_prisma/
error.rs

1//! Typed errors for the generated Prisma-style client and mapping to [`nestrs::HttpException`].
2
3use nestrs::HttpException;
4#[cfg(not(feature = "sqlx"))]
5use nestrs::InternalServerErrorException;
6#[cfg(feature = "sqlx")]
7use nestrs::{
8    ConflictException, InternalServerErrorException, NotFoundException, ServiceUnavailableException,
9};
10
11#[cfg(feature = "sqlx")]
12#[derive(Debug, thiserror::Error)]
13pub enum PrismaError {
14    #[error("database pool: {0}")]
15    PoolInit(String),
16    #[error(transparent)]
17    Sqlx(#[from] sqlx::Error),
18    #[error("record not found")]
19    RowNotFound,
20    #[error("unique constraint violated: {0}")]
21    UniqueViolation(String),
22    #[error("{0}")]
23    Other(String),
24}
25
26#[cfg(feature = "sqlx")]
27impl PrismaError {
28    pub fn other(msg: impl Into<String>) -> Self {
29        Self::Other(msg.into())
30    }
31
32    pub fn from_sqlx(e: sqlx::Error) -> Self {
33        if matches!(e, sqlx::Error::RowNotFound) {
34            return Self::RowNotFound;
35        }
36        if let Some(db) = e.as_database_error() {
37            if db.is_unique_violation() {
38                return Self::UniqueViolation(db.message().to_string());
39            }
40        }
41        Self::Sqlx(e)
42    }
43}
44
45#[cfg(feature = "sqlx")]
46impl From<PrismaError> for HttpException {
47    fn from(value: PrismaError) -> Self {
48        match value {
49            PrismaError::RowNotFound => NotFoundException::new("record not found"),
50            PrismaError::UniqueViolation(msg) => ConflictException::new(msg),
51            PrismaError::PoolInit(msg) => ServiceUnavailableException::new(msg),
52            PrismaError::Sqlx(e) => {
53                if let Some(db) = e.as_database_error() {
54                    if db.is_unique_violation() {
55                        return ConflictException::new(db.message());
56                    }
57                }
58                match &e {
59                    sqlx::Error::PoolClosed | sqlx::Error::Protocol(_) => {
60                        ServiceUnavailableException::new(e.to_string())
61                    }
62                    _ => InternalServerErrorException::new(e.to_string()),
63                }
64            }
65            PrismaError::Other(msg) => InternalServerErrorException::new(msg),
66        }
67    }
68}
69
70#[cfg(not(feature = "sqlx"))]
71#[derive(Debug, thiserror::Error)]
72pub enum PrismaError {
73    #[error("enable feature `sqlx` on nestrs-prisma for the generated Prisma client")]
74    ClientDisabled,
75}
76
77#[cfg(not(feature = "sqlx"))]
78impl From<PrismaError> for HttpException {
79    fn from(e: PrismaError) -> Self {
80        InternalServerErrorException::new(e.to_string())
81    }
82}