use saddle_core::{ErrorKind, SaddleError};
pub(crate) fn connection_unavailable() -> SaddleError {
SaddleError::new(
ErrorKind::Unavailable,
"db.connection_unavailable",
"database connection is unavailable",
)
}
pub(crate) fn query_failed() -> SaddleError {
SaddleError::new(
ErrorKind::Infrastructure,
"db.query_failed",
"database operation failed",
)
}
pub(crate) fn transaction_begin_failed() -> SaddleError {
SaddleError::new(
ErrorKind::Infrastructure,
"db.transaction_begin_failed",
"database transaction could not be started",
)
}
pub(crate) fn transaction_commit_failed() -> SaddleError {
SaddleError::new(
ErrorKind::Infrastructure,
"db.transaction_commit_failed",
"database transaction could not be committed",
)
}
pub(crate) fn transaction_rollback_failed() -> SaddleError {
SaddleError::new(
ErrorKind::Infrastructure,
"db.transaction_rollback_failed",
"database transaction could not be rolled back",
)
}
pub(crate) fn map_operation_error(error: sqlx::Error) -> SaddleError {
match error {
sqlx::Error::PoolTimedOut | sqlx::Error::PoolClosed | sqlx::Error::Io(_) => {
connection_unavailable()
}
_ => query_failed(),
}
}
pub(crate) fn invalid_column() -> SaddleError {
SaddleError::new(
ErrorKind::Internal,
"db.invalid_column",
"database result did not match the expected column type",
)
}
pub(crate) fn result_limit_exceeded() -> SaddleError {
SaddleError::new(
ErrorKind::Infrastructure,
"db.result_limit_exceeded",
"database query exceeded the V1 row limit",
)
}
pub(crate) fn unsupported_column_type() -> SaddleError {
SaddleError::new(
ErrorKind::Infrastructure,
"db.unsupported_column_type",
"database returned a column type outside the V1 controlled API",
)
}
pub(crate) fn transaction_cancelled() -> SaddleError {
SaddleError::new(
ErrorKind::Infrastructure,
"db.transaction_cancelled",
"database transaction was cancelled and rolled back",
)
}
pub(crate) fn cleanup_failed() -> SaddleError {
SaddleError::new(
ErrorKind::Internal,
"db.cleanup_failed",
"database cancellation cleanup worker failed",
)
}
pub(crate) fn invalid_config(message: &'static str) -> SaddleError {
SaddleError::new(ErrorKind::InvalidArgument, "db.invalid_config", message)
}
pub(crate) fn invalid_statement(message: &'static str) -> SaddleError {
SaddleError::new(ErrorKind::InvalidArgument, "db.invalid_statement", message)
}
#[cfg(test)]
mod tests {
use std::io;
use super::*;
#[test]
fn sqlx_details_are_replaced_by_stable_safe_errors() {
let protocol = map_operation_error(sqlx::Error::Protocol("password=secret".to_owned()));
assert_eq!(protocol.kind(), ErrorKind::Infrastructure);
assert_eq!(protocol.code(), "db.query_failed");
assert!(!protocol.to_string().contains("secret"));
let io = map_operation_error(sqlx::Error::Io(io::Error::other("host-secret")));
assert_eq!(io.kind(), ErrorKind::Unavailable);
assert_eq!(io.code(), "db.connection_unavailable");
assert!(!io.to_string().contains("host-secret"));
}
}