diff --git a/sqlx-core/src/error.rs b/sqlx-core/src/error.rs index 7b21e9d567..4720f2c092 100644 --- a/sqlx-core/src/error.rs +++ b/sqlx-core/src/error.rs @@ -41,12 +41,49 @@ pub struct MismatchedTypeError { pub source: Option, } +fn rust_sql_type>() -> String { + if is_any_db::() { + return "".to_string(); + } + + T::type_info().name().to_string() +} + +#[cfg(all( + feature = "any", + any( + feature = "postgres", + feature = "mysql", + feature = "mssql", + feature = "sqlite", + feature = "odbc" + ) +))] +fn is_any_db() -> bool { + std::any::TypeId::of::() == std::any::TypeId::of::() +} + +#[cfg(not(all( + feature = "any", + any( + feature = "postgres", + feature = "mysql", + feature = "mssql", + feature = "sqlite", + feature = "odbc" + ) +)))] +fn is_any_db() -> bool { + let _ = std::any::TypeId::of::(); + false +} + impl MismatchedTypeError { /// Create a new mismatched type error without a source. pub fn new>(ty: &DB::TypeInfo) -> Self { Self { rust_type: type_name::().to_string(), - rust_sql_type: T::type_info().name().to_string(), + rust_sql_type: rust_sql_type::(), sql_type: ty.name().to_string(), source: None, } @@ -56,7 +93,7 @@ impl MismatchedTypeError { pub fn with_source>(ty: &DB::TypeInfo, source: BoxDynError) -> Self { Self { rust_type: type_name::().to_string(), - rust_sql_type: T::type_info().name().to_string(), + rust_sql_type: rust_sql_type::(), sql_type: ty.name().to_string(), source: Some(source), } @@ -182,19 +219,33 @@ impl Error { } pub(crate) fn mismatched_types>(ty: &DB::TypeInfo) -> BoxDynError { + let rust_sql_type = rust_sql_type::(); Box::new(MismatchedTypeError { rust_type: format!( "{} ({}compatible with SQL type `{}`)", type_name::(), if T::compatible(ty) { "" } else { "in" }, - T::type_info().name() + rust_sql_type ), - rust_sql_type: T::type_info().name().to_string(), + rust_sql_type, sql_type: ty.name().to_string(), source: None, }) } +#[cfg(all(test, feature = "any", feature = "postgres"))] +mod tests { + use crate::any::Any; + use crate::error::mismatched_types; + use crate::postgres::PgTypeInfo; + + #[test] + fn mismatched_types_any_does_not_panic() { + let ty = crate::any::AnyTypeInfo::from(PgTypeInfo::with_name("TEXT")); + assert!(std::panic::catch_unwind(|| mismatched_types::(&ty)).is_ok()); + } +} + /// An error that was returned from the database. pub trait DatabaseError: 'static + Send + Sync + StdError { /// The primary, human-readable error message.