mirror of
https://github.com/launchbadge/sqlx
synced 2024-11-14 16:17:15 +00:00
Improve docs around errors
This commit is contained in:
parent
9d7eff2ca7
commit
abb7d12087
6 changed files with 49 additions and 18 deletions
|
@ -8,9 +8,8 @@ use crate::{
|
|||
use crossbeam_queue::SegQueue;
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use futures_channel::oneshot::{channel, Sender};
|
||||
use futures_util::TryFutureExt;
|
||||
use futures_core::{future::BoxFuture, stream::BoxStream};
|
||||
use futures_util::stream::StreamExt;
|
||||
use futures_util::{stream::StreamExt, TryFutureExt};
|
||||
use std::{
|
||||
io,
|
||||
ops::{Deref, DerefMut},
|
||||
|
@ -37,13 +36,19 @@ pub trait RawConnection: Send {
|
|||
///
|
||||
/// This method is not required to be called. A database server will eventually notice
|
||||
/// and clean up not fully closed connections.
|
||||
///
|
||||
///
|
||||
/// It is safe to close an already closed connection.
|
||||
fn close<'c>(&'c mut self) -> BoxFuture<'c, Result<(), Error>>;
|
||||
|
||||
/// Verifies a connection to the database is still alive.
|
||||
fn ping<'c>(&'c mut self) -> BoxFuture<'c, Result<(), Error>> {
|
||||
Box::pin(self.execute("SELECT 1", <Self::Backend as Backend>::QueryParameters::new()).map_ok(|_| ()))
|
||||
Box::pin(
|
||||
self.execute(
|
||||
"SELECT 1",
|
||||
<Self::Backend as Backend>::QueryParameters::new(),
|
||||
)
|
||||
.map_ok(|_| ()),
|
||||
)
|
||||
}
|
||||
|
||||
fn execute<'c>(
|
||||
|
@ -103,7 +108,7 @@ where
|
|||
///
|
||||
/// This method is not required to be called. A database server will eventually notice
|
||||
/// and clean up not fully closed connections.
|
||||
///
|
||||
///
|
||||
/// It is safe to close an already closed connection.
|
||||
pub async fn close(&self) -> crate::Result<()> {
|
||||
let mut conn = self.acquire().await;
|
||||
|
|
39
src/error.rs
39
src/error.rs
|
@ -4,8 +4,10 @@ use std::{
|
|||
io,
|
||||
};
|
||||
|
||||
/// A convenient Result instantiation appropriate for SQLx.
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// A generic error that represents all the ways a method can fail inside of SQLx.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// Error communicating with the database backend.
|
||||
|
@ -24,23 +26,46 @@ pub enum Error {
|
|||
Io(io::Error),
|
||||
|
||||
/// An error was returned by the database backend.
|
||||
Database(Box<dyn DbError + Send + Sync>),
|
||||
Database(Box<dyn DatabaseError + Send + Sync>),
|
||||
|
||||
/// No rows were returned by a query expected to return at least one row.
|
||||
NotFound,
|
||||
|
||||
/// More than one row was returned by a query expected to return exactly one row.
|
||||
FoundMoreThanOne,
|
||||
|
||||
// TODO: Remove and replace with `#[non_exhaustive]` when possible
|
||||
#[doc(hidden)]
|
||||
__Nonexhaustive,
|
||||
}
|
||||
|
||||
// TODO: Forward causes where present
|
||||
impl StdError for Error {}
|
||||
impl StdError for Error {
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
match self {
|
||||
Error::Io(error) => Some(error),
|
||||
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Don't just forward to debug
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
match self {
|
||||
Error::Io(error) => write!(f, "{}", error),
|
||||
|
||||
Error::Database(error) => f.write_str(error.message()),
|
||||
|
||||
Error::NotFound => f.write_str("found no rows when we expected at least one"),
|
||||
|
||||
Error::FoundMoreThanOne => {
|
||||
f.write_str("found more than one row when we expected exactly one")
|
||||
}
|
||||
|
||||
Error::__Nonexhaustive => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +78,7 @@ impl From<io::Error> for Error {
|
|||
|
||||
impl<T> From<T> for Error
|
||||
where
|
||||
T: 'static + DbError,
|
||||
T: 'static + DatabaseError,
|
||||
{
|
||||
#[inline]
|
||||
fn from(err: T) -> Self {
|
||||
|
@ -62,7 +87,7 @@ where
|
|||
}
|
||||
|
||||
/// An error that was returned by the database backend.
|
||||
pub trait DbError: Debug + Send + Sync {
|
||||
pub trait DatabaseError: Debug + Send + Sync {
|
||||
fn message(&self) -> &str;
|
||||
|
||||
// TODO: Expose more error properties
|
||||
|
|
|
@ -30,6 +30,7 @@ pub mod serialize;
|
|||
mod sql;
|
||||
pub mod types;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use self::{
|
||||
connection::Connection,
|
||||
error::{Error, Result},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::{
|
||||
protocol::{self, Decode, Encode, Message, Terminate},
|
||||
Postgres, PostgresError, PostgresQueryParameters, PostgresRow,
|
||||
Postgres, PostgresDatabaseError, PostgresQueryParameters, PostgresRow,
|
||||
};
|
||||
use crate::{
|
||||
connection::RawConnection,
|
||||
|
@ -200,7 +200,7 @@ impl PostgresRawConnection {
|
|||
Message::Response(body) => {
|
||||
if body.severity().is_error() {
|
||||
// This is an error, stop the world and bubble as an error
|
||||
return Err(PostgresError(body).into());
|
||||
return Err(PostgresDatabaseError(body).into());
|
||||
} else {
|
||||
// This is a _warning_
|
||||
// TODO: Do we *want* to do anything with these
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use super::protocol::Response;
|
||||
use crate::error::DbError;
|
||||
use crate::error::DatabaseError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PostgresError(pub(super) Box<Response>);
|
||||
pub struct PostgresDatabaseError(pub(super) Box<Response>);
|
||||
|
||||
impl DbError for PostgresError {
|
||||
impl DatabaseError for PostgresDatabaseError {
|
||||
fn message(&self) -> &str {
|
||||
self.0.message()
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ mod row;
|
|||
pub mod types;
|
||||
|
||||
pub use self::{
|
||||
backend::Postgres, connection::PostgresRawConnection, error::PostgresError,
|
||||
backend::Postgres, connection::PostgresRawConnection, error::PostgresDatabaseError,
|
||||
query::PostgresQueryParameters, row::PostgresRow,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue