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_queue::SegQueue;
|
||||||
use crossbeam_utils::atomic::AtomicCell;
|
use crossbeam_utils::atomic::AtomicCell;
|
||||||
use futures_channel::oneshot::{channel, Sender};
|
use futures_channel::oneshot::{channel, Sender};
|
||||||
use futures_util::TryFutureExt;
|
|
||||||
use futures_core::{future::BoxFuture, stream::BoxStream};
|
use futures_core::{future::BoxFuture, stream::BoxStream};
|
||||||
use futures_util::stream::StreamExt;
|
use futures_util::{stream::StreamExt, TryFutureExt};
|
||||||
use std::{
|
use std::{
|
||||||
io,
|
io,
|
||||||
ops::{Deref, DerefMut},
|
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
|
/// This method is not required to be called. A database server will eventually notice
|
||||||
/// and clean up not fully closed connections.
|
/// and clean up not fully closed connections.
|
||||||
///
|
///
|
||||||
/// It is safe to close an already closed connection.
|
/// It is safe to close an already closed connection.
|
||||||
fn close<'c>(&'c mut self) -> BoxFuture<'c, Result<(), Error>>;
|
fn close<'c>(&'c mut self) -> BoxFuture<'c, Result<(), Error>>;
|
||||||
|
|
||||||
/// Verifies a connection to the database is still alive.
|
/// Verifies a connection to the database is still alive.
|
||||||
fn ping<'c>(&'c mut self) -> BoxFuture<'c, Result<(), Error>> {
|
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>(
|
fn execute<'c>(
|
||||||
|
@ -103,7 +108,7 @@ where
|
||||||
///
|
///
|
||||||
/// This method is not required to be called. A database server will eventually notice
|
/// This method is not required to be called. A database server will eventually notice
|
||||||
/// and clean up not fully closed connections.
|
/// and clean up not fully closed connections.
|
||||||
///
|
///
|
||||||
/// It is safe to close an already closed connection.
|
/// It is safe to close an already closed connection.
|
||||||
pub async fn close(&self) -> crate::Result<()> {
|
pub async fn close(&self) -> crate::Result<()> {
|
||||||
let mut conn = self.acquire().await;
|
let mut conn = self.acquire().await;
|
||||||
|
|
39
src/error.rs
39
src/error.rs
|
@ -4,8 +4,10 @@ use std::{
|
||||||
io,
|
io,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A convenient Result instantiation appropriate for SQLx.
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
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)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Error communicating with the database backend.
|
/// Error communicating with the database backend.
|
||||||
|
@ -24,23 +26,46 @@ pub enum Error {
|
||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
|
|
||||||
/// An error was returned by the database backend.
|
/// 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.
|
/// No rows were returned by a query expected to return at least one row.
|
||||||
NotFound,
|
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
|
// TODO: Remove and replace with `#[non_exhaustive]` when possible
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
__Nonexhaustive,
|
__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 {
|
impl Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
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
|
impl<T> From<T> for Error
|
||||||
where
|
where
|
||||||
T: 'static + DbError,
|
T: 'static + DatabaseError,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(err: T) -> Self {
|
fn from(err: T) -> Self {
|
||||||
|
@ -62,7 +87,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An error that was returned by the database backend.
|
/// 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;
|
fn message(&self) -> &str;
|
||||||
|
|
||||||
// TODO: Expose more error properties
|
// TODO: Expose more error properties
|
||||||
|
|
|
@ -30,6 +30,7 @@ pub mod serialize;
|
||||||
mod sql;
|
mod sql;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
pub use self::{
|
pub use self::{
|
||||||
connection::Connection,
|
connection::Connection,
|
||||||
error::{Error, Result},
|
error::{Error, Result},
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{
|
use super::{
|
||||||
protocol::{self, Decode, Encode, Message, Terminate},
|
protocol::{self, Decode, Encode, Message, Terminate},
|
||||||
Postgres, PostgresError, PostgresQueryParameters, PostgresRow,
|
Postgres, PostgresDatabaseError, PostgresQueryParameters, PostgresRow,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
connection::RawConnection,
|
connection::RawConnection,
|
||||||
|
@ -200,7 +200,7 @@ impl PostgresRawConnection {
|
||||||
Message::Response(body) => {
|
Message::Response(body) => {
|
||||||
if body.severity().is_error() {
|
if body.severity().is_error() {
|
||||||
// This is an error, stop the world and bubble as an error
|
// This is an error, stop the world and bubble as an error
|
||||||
return Err(PostgresError(body).into());
|
return Err(PostgresDatabaseError(body).into());
|
||||||
} else {
|
} else {
|
||||||
// This is a _warning_
|
// This is a _warning_
|
||||||
// TODO: Do we *want* to do anything with these
|
// TODO: Do we *want* to do anything with these
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use super::protocol::Response;
|
use super::protocol::Response;
|
||||||
use crate::error::DbError;
|
use crate::error::DatabaseError;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[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 {
|
fn message(&self) -> &str {
|
||||||
self.0.message()
|
self.0.message()
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ mod row;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
backend::Postgres, connection::PostgresRawConnection, error::PostgresError,
|
backend::Postgres, connection::PostgresRawConnection, error::PostgresDatabaseError,
|
||||||
query::PostgresQueryParameters, row::PostgresRow,
|
query::PostgresQueryParameters, row::PostgresRow,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue