Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(query-engine-wasm): exclude native-drivers only errors from wasm32 target #4616

Merged
merged 17 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libs/user-facing-errors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ quaint = { path = "../../quaint", optional = true }

[features]
default = []
# native = ["quaint/native"]
sql = ["quaint"]
397 changes: 207 additions & 190 deletions libs/user-facing-errors/src/quaint.rs

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions quaint/src/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ mod connection_info;

pub mod external;
pub mod metrics;
#[cfg(feature = "native")]
pub mod native;
mod queryable;
mod result_set;
#[cfg(any(feature = "mssql-native", feature = "postgresql-native", feature = "mysql-native"))]
Expand All @@ -22,6 +24,10 @@ mod type_identifier;

pub use self::result_set::*;
pub use connection_info::*;

#[cfg(feature = "native")]
pub use native::*;

pub use external::*;
pub use queryable::*;
pub use transaction::*;
Expand Down
226 changes: 122 additions & 104 deletions quaint/src/connector/connection_info.rs

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions quaint/src/connector/mssql/native/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::error::{DatabaseConstraint, Error, ErrorKind};
use crate::error::{DatabaseConstraint, Error, ErrorKind, NativeErrorKind};
use tiberius::error::IoErrorKind;

impl From<tiberius::error::Error> for Error {
Expand All @@ -8,17 +8,19 @@ impl From<tiberius::error::Error> for Error {
kind: IoErrorKind::UnexpectedEof,
message,
} => {
let mut builder = Error::builder(ErrorKind::ConnectionClosed);
let mut builder = Error::builder(ErrorKind::Native(NativeErrorKind::ConnectionClosed));
builder.set_original_message(message);
builder.build()
}
e @ tiberius::error::Error::Io { .. } => Error::builder(ErrorKind::ConnectionError(e.into())).build(),
e @ tiberius::error::Error::Io { .. } => {
Error::builder(ErrorKind::Native(NativeErrorKind::ConnectionError(e.into()))).build()
}
tiberius::error::Error::Tls(message) => {
let message = format!(
"The TLS settings didn't allow the connection to be established. Please review your connection string. (error: {message})"
);

Error::builder(ErrorKind::TlsError { message }).build()
Error::builder(ErrorKind::Native(NativeErrorKind::TlsError { message })).build()
}
tiberius::error::Error::Server(e) if [3902u32, 3903u32, 3971u32].iter().any(|code| e.code() == *code) => {
let kind = ErrorKind::TransactionAlreadyClosed(e.message().to_string());
Expand Down
12 changes: 7 additions & 5 deletions quaint/src/connector/mysql/native/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
connector::mysql::error::MysqlError,
error::{Error, ErrorKind},
error::{Error, ErrorKind, NativeErrorKind},
};
use mysql_async as my;

Expand All @@ -17,14 +17,16 @@ impl From<&my::ServerError> for MysqlError {
impl From<my::Error> for Error {
fn from(e: my::Error) -> Error {
match e {
my::Error::Io(my::IoError::Tls(err)) => Error::builder(ErrorKind::TlsError {
my::Error::Io(my::IoError::Tls(err)) => Error::builder(ErrorKind::Native(NativeErrorKind::TlsError {
message: err.to_string(),
})
}))
.build(),
my::Error::Io(my::IoError::Io(err)) if err.kind() == std::io::ErrorKind::UnexpectedEof => {
Error::builder(ErrorKind::ConnectionClosed).build()
Error::builder(ErrorKind::Native(NativeErrorKind::ConnectionClosed)).build()
}
my::Error::Io(io_error) => {
Error::builder(ErrorKind::Native(NativeErrorKind::ConnectionError(io_error.into()))).build()
}
my::Error::Io(io_error) => Error::builder(ErrorKind::ConnectionError(io_error.into())).build(),
my::Error::Driver(e) => Error::builder(ErrorKind::QueryError(e.into())).build(),
my::Error::Server(ref server_error) => {
let mysql_error: MysqlError = server_error.into();
Expand Down
31 changes: 31 additions & 0 deletions quaint/src/connector/native.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#[cfg(feature = "mssql")]
use crate::connector::MssqlUrl;
#[cfg(feature = "mysql")]
use crate::connector::MysqlUrl;
#[cfg(feature = "postgresql")]
use crate::connector::PostgresUrl;

/// General information about a SQL connection, provided by native Rust drivers.
#[cfg(not(target_arch = "wasm32"))]
#[derive(Debug, Clone)]
pub enum NativeConnectionInfo {
/// A PostgreSQL connection URL.
#[cfg(feature = "postgresql")]
Postgres(PostgresUrl),
/// A MySQL connection URL.
#[cfg(feature = "mysql")]
Mysql(MysqlUrl),
/// A SQL Server connection URL.
#[cfg(feature = "mssql")]
Mssql(MssqlUrl),
/// A SQLite connection URL.
#[cfg(feature = "sqlite")]
Sqlite {
/// The filesystem path of the SQLite database.
file_path: String,
/// The name the database is bound to - Always "main"
db_name: String,
},
#[cfg(feature = "sqlite")]
InMemorySqlite { db_name: String },
}
21 changes: 13 additions & 8 deletions quaint/src/connector/postgres/native/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use tokio_postgres::error::DbError;

use crate::{
connector::postgres::error::PostgresError,
error::{Error, ErrorKind},
error::{Error, ErrorKind, NativeErrorKind},
};

impl From<&DbError> for PostgresError {
Expand All @@ -21,7 +21,7 @@ impl From<&DbError> for PostgresError {
impl From<tokio_postgres::error::Error> for Error {
fn from(e: tokio_postgres::error::Error) -> Error {
if e.is_closed() {
return Error::builder(ErrorKind::ConnectionClosed).build();
return Error::builder(ErrorKind::Native(NativeErrorKind::ConnectionClosed)).build();
}

if let Some(db_error) = e.as_db_error() {
Expand All @@ -46,7 +46,7 @@ impl From<tokio_postgres::error::Error> for Error {

match reason.as_str() {
"error connecting to server: timed out" => {
let mut builder = Error::builder(ErrorKind::ConnectTimeout);
let mut builder = Error::builder(ErrorKind::Native(NativeErrorKind::ConnectTimeout));

if let Some(code) = code {
builder.set_original_code(code);
Expand All @@ -57,9 +57,9 @@ impl From<tokio_postgres::error::Error> for Error {
} // sigh...
// https://github.com/sfackler/rust-postgres/blob/0c84ed9f8201f4e5b4803199a24afa2c9f3723b2/tokio-postgres/src/connect_tls.rs#L37
"error performing TLS handshake: server does not support TLS" => {
let mut builder = Error::builder(ErrorKind::TlsError {
let mut builder = Error::builder(ErrorKind::Native(NativeErrorKind::TlsError {
message: reason.clone(),
});
}));

if let Some(code) = code {
builder.set_original_code(code);
Expand Down Expand Up @@ -105,7 +105,12 @@ fn try_extracting_io_error(err: &tokio_postgres::error::Error) -> Option<Error>

err.source()
.and_then(|err| err.downcast_ref::<std::io::Error>())
.map(|err| ErrorKind::ConnectionError(Box::new(std::io::Error::new(err.kind(), format!("{err}")))))
.map(|err| {
ErrorKind::Native(NativeErrorKind::ConnectionError(Box::new(std::io::Error::new(
err.kind(),
format!("{err}"),
))))
})
.map(|kind| Error::builder(kind).build())
}

Expand All @@ -117,9 +122,9 @@ impl From<native_tls::Error> for Error {

impl From<&native_tls::Error> for Error {
fn from(e: &native_tls::Error) -> Error {
let kind = ErrorKind::TlsError {
let kind = ErrorKind::Native(NativeErrorKind::TlsError {
message: format!("{e}"),
};
});

Error::builder(kind).build()
}
Expand Down
29 changes: 15 additions & 14 deletions quaint/src/connector/postgres/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod error;
pub(crate) use crate::connector::postgres::url::PostgresUrl;
use crate::connector::postgres::url::{Hidden, SslAcceptMode, SslParams};
use crate::connector::{timeout, IsolationLevel, Transaction};
use crate::error::NativeErrorKind;

use crate::{
ast::{Query, Value},
Expand Down Expand Up @@ -93,9 +94,9 @@ impl SslParams {

if let Some(ref cert_file) = self.certificate_file {
let cert = fs::read(cert_file).map_err(|err| {
Error::builder(ErrorKind::TlsError {
Error::builder(ErrorKind::Native(NativeErrorKind::TlsError {
message: format!("cert file not found ({err})"),
})
}))
.build()
})?;

Expand All @@ -104,9 +105,9 @@ impl SslParams {

if let Some(ref identity_file) = self.identity_file {
let db = fs::read(identity_file).map_err(|err| {
Error::builder(ErrorKind::TlsError {
Error::builder(ErrorKind::Native(NativeErrorKind::TlsError {
message: format!("identity file not found ({err})"),
})
}))
.build()
})?;
let password = self.identity_password.0.as_deref().unwrap_or("");
Expand Down Expand Up @@ -305,11 +306,11 @@ impl PostgreSql {
if params.len() > i16::MAX as usize {
// tokio_postgres would return an error here. Let's avoid calling the driver
// and return an error early.
let kind = ErrorKind::QueryInvalidInput(format!(
let kind = ErrorKind::Native(NativeErrorKind::QueryInvalidInput(format!(
"too many bind variables in prepared statement, expected maximum of {}, received {}",
i16::MAX,
params.len()
));
)));
Err(Error::builder(kind).build())
} else {
Ok(())
Expand Down Expand Up @@ -371,10 +372,10 @@ impl Queryable for PostgreSql {
let stmt = self.fetch_cached(sql, &[]).await?;

if stmt.params().len() != params.len() {
let kind = ErrorKind::IncorrectNumberOfParameters {
let kind = ErrorKind::Native(NativeErrorKind::IncorrectNumberOfParameters {
expected: stmt.params().len(),
actual: params.len(),
};
});

return Err(Error::builder(kind).build());
}
Expand All @@ -401,10 +402,10 @@ impl Queryable for PostgreSql {
let stmt = self.fetch_cached(sql, params).await?;

if stmt.params().len() != params.len() {
let kind = ErrorKind::IncorrectNumberOfParameters {
let kind = ErrorKind::Native(NativeErrorKind::IncorrectNumberOfParameters {
expected: stmt.params().len(),
actual: params.len(),
};
});

return Err(Error::builder(kind).build());
}
Expand Down Expand Up @@ -437,10 +438,10 @@ impl Queryable for PostgreSql {
let stmt = self.fetch_cached(sql, &[]).await?;

if stmt.params().len() != params.len() {
let kind = ErrorKind::IncorrectNumberOfParameters {
let kind = ErrorKind::Native(NativeErrorKind::IncorrectNumberOfParameters {
expected: stmt.params().len(),
actual: params.len(),
};
});

return Err(Error::builder(kind).build());
}
Expand All @@ -461,10 +462,10 @@ impl Queryable for PostgreSql {
let stmt = self.fetch_cached(sql, params).await?;

if stmt.params().len() != params.len() {
let kind = ErrorKind::IncorrectNumberOfParameters {
let kind = ErrorKind::Native(NativeErrorKind::IncorrectNumberOfParameters {
expected: stmt.params().len(),
actual: params.len(),
};
});

return Err(Error::builder(kind).build());
}
Expand Down
4 changes: 2 additions & 2 deletions quaint/src/connector/postgres/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ mod tests {
match res {
Ok(_) => unreachable!(),
Err(e) => match e.kind() {
ErrorKind::TlsError { .. } => (),
ErrorKind::Native(NativeErrorKind::TlsError { .. }) => (),
other => panic!("{:#?}", other),
},
}
Expand All @@ -626,7 +626,7 @@ mod tests {
match res {
Ok(_) => unreachable!(),
Err(e) => match e.kind() {
ErrorKind::IncorrectNumberOfParameters { expected, actual } => {
ErrorKind::Native(NativeErrorKind::IncorrectNumberOfParameters { expected, actual }) => {
assert_eq!(1, *expected);
assert_eq!(2, *actual);
}
Expand Down
6 changes: 5 additions & 1 deletion quaint/src/connector/timeout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ use crate::error::{Error, ErrorKind};
use futures::Future;
use std::time::Duration;

#[cfg(feature = "native")]
pub async fn connect<T, F, E>(duration: Option<Duration>, f: F) -> crate::Result<T>
where
F: Future<Output = std::result::Result<T, E>>,
E: Into<Error>,
{
timeout(duration, f, || Error::builder(ErrorKind::ConnectTimeout).build()).await
timeout(duration, f, || {
Error::builder(ErrorKind::Native(crate::error::NativeErrorKind::ConnectTimeout)).build()
})
.await
}

pub async fn socket<T, F, E>(duration: Option<Duration>, f: F) -> crate::Result<T>
Expand Down
Loading
Loading