Repository: launchbadge/sqlx
File: sqlx-core/src/error.rs (Rust)

Code before:
    PoolTimedOut,

    /// [`Pool::close`] was called while we were waiting in [`Pool::acquire`].
    ///
    /// [`Pool::acquire`]: crate::pool::Pool::acquire
    /// [`Pool::close`]: crate::pool::Pool::close
    #[error("attempted to acquire a connection on a closed pool")]
    PoolClosed,

    /// A background worker has crashed.
    #[error("attempted to communicate with a crashed background worker")]
    WorkerCrashed,

    #[cfg(feature = "migrate")]
    #[error("{0}")]
    Migrate(#[source] Box<crate::migrate::MigrateError>),

    /// LTree labels can only contain [A-Za-z0-9_]
    #[cfg(feature = "ltree")]
    #[error("ltree label cotains invalid characters")]
    InvalidLtreeLabel,

    /// LTree version not supported
    #[cfg(feature = "ltree")]
    #[error("ltree version not supported")]
    InvalidLtreeVersion,
}

impl StdError for Box<dyn DatabaseError> {}

impl Error {
    pub fn into_database_error(self) -> Option<Box<dyn DatabaseError + 'static>> {
        match self {
            Error::Database(err) => Some(err),
            _ => None,
        }
    }

    pub fn as_database_error(&self) -> Option<&(dyn DatabaseError + 'static)> {
        match self {
            Error::Database(err) => Some(&**err),
            _ => None,
        }
    }

    #[allow(dead_code)]
    #[inline]
    pub(crate) fn protocol(err: impl Display) -> Self {
        Error::Protocol(err.to_string())
    }


Review comment (suggestion):
These errors are too specific for this enum.

I'd suggest creating a separate error type for the
`FromStr` impl of `PgLtree` and then in decode return it boxed in `Error::Decode`. 

Code after:
    PoolTimedOut,

    /// [`Pool::close`] was called while we were waiting in [`Pool::acquire`].
    ///
    /// [`Pool::acquire`]: crate::pool::Pool::acquire
    /// [`Pool::close`]: crate::pool::Pool::close
    #[error("attempted to acquire a connection on a closed pool")]
    PoolClosed,

    /// A background worker has crashed.
    #[error("attempted to communicate with a crashed background worker")]
    WorkerCrashed,

    #[cfg(feature = "migrate")]
    #[error("{0}")]
    Migrate(#[source] Box<crate::migrate::MigrateError>),
}

impl StdError for Box<dyn DatabaseError> {}

impl Error {
    pub fn into_database_error(self) -> Option<Box<dyn DatabaseError + 'static>> {
        match self {
            Error::Database(err) => Some(err),
            _ => None,
        }
    }

    pub fn as_database_error(&self) -> Option<&(dyn DatabaseError + 'static)> {
        match self {
            Error::Database(err) => Some(&**err),
            _ => None,
        }
    }

    #[allow(dead_code)]
    #[inline]
    pub(crate) fn protocol(err: impl Display) -> Self {
        Error::Protocol(err.to_string())
    }

    #[allow(dead_code)]
    #[inline]
    pub(crate) fn config(err: impl StdError + Send + Sync + 'static) -> Self {
        Error::Configuration(err.into())
    }
}

pub(crate) fn mismatched_types<DB: Database, T: Type<DB>>(ty: &DB::TypeInfo) -> BoxDynError {
    // TODO: `#name` only produces `TINYINT` but perhaps we want to show `TINYINT(1)`
    format!(