Add constraint violation and diesel error types
This add the constraint violation error type along with conversion
methods for diesel errors to the commits store error module. This will
be useful for making commit operation atomic.
use std::error::Error;
use std::fmt;
+#[cfg(feature = "diesel")]
+use crate::error::ConstraintViolationType;
use crate::error::{ConstraintViolationError, InternalError, ResourceTemporarilyUnavailableError};
/// Represents CommitStore errors
@@ -52,6 +54,7 @@ impl fmt::Display for CommitStoreError {
#[derive(Debug)]
pub enum CommitEventError {
InternalError(InternalError),
+ ConstraintViolationError(ConstraintViolationError),
ResourceTemporarilyUnavailableError(ResourceTemporarilyUnavailableError),
}
@@ -59,6 +62,7 @@ impl Error for CommitEventError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
CommitEventError::InternalError(err) => Some(err),
+ CommitEventError::ConstraintViolationError(err) => Some(err),
CommitEventError::ResourceTemporarilyUnavailableError(err) => Some(err),
}
}
@@ -68,7 +72,44 @@ impl fmt::Display for CommitEventError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CommitEventError::InternalError(err) => err.fmt(f),
+ CommitEventError::ConstraintViolationError(err) => err.fmt(f),
CommitEventError::ResourceTemporarilyUnavailableError(err) => err.fmt(f),
}
}
}
+
+#[cfg(feature = "diesel")]
+impl From<diesel::result::Error> for CommitEventError {
+ fn from(err: diesel::result::Error) -> Self {
+ match err {
+ diesel::result::Error::DatabaseError(
+ diesel::result::DatabaseErrorKind::UniqueViolation,
+ _,
+ ) => CommitEventError::ConstraintViolationError(
+ ConstraintViolationError::from_source_with_violation_type(
+ ConstraintViolationType::Unique,
+ Box::new(err),
+ ),
+ ),
+ diesel::result::Error::DatabaseError(
+ diesel::result::DatabaseErrorKind::ForeignKeyViolation,
+ _,
+ ) => CommitEventError::ConstraintViolationError(
+ ConstraintViolationError::from_source_with_violation_type(
+ ConstraintViolationType::ForeignKey,
+ Box::new(err),
+ ),
+ ),
+ _ => CommitEventError::InternalError(InternalError::from_source(Box::new(err))),
+ }
+ }
+}
+
+#[cfg(feature = "diesel")]
+impl From<diesel::r2d2::PoolError> for CommitEventError {
+ fn from(err: diesel::r2d2::PoolError) -> CommitEventError {
+ CommitEventError::ResourceTemporarilyUnavailableError(
+ ResourceTemporarilyUnavailableError::from_source(Box::new(err)),
+ )
+ }
+}
