pub enum Error {
InvalidData(String),
Conversion(String),
DatabaseError(Error),
InvalidArgument(String),
}Expand description
The main error type for Bottle ORM operations.
This enum represents all possible errors that can occur during ORM operations.
It uses the thiserror crate to automatically implement std::error::Error
and provide helpful error messages.
§Variants
InvalidData- Data validation errorsDatabaseError- Wrapped sqlx database errorsInvalidArgument- Invalid arguments passed to methods
§Display Format
Each variant has a custom display format defined via the #[error(...)] attribute:
InvalidData: “Invalid Data {message}: {message}”DatabaseError: “Database error {inner_error}:”InvalidArgument: “Invalid argument {message}: {message}”
§Example
use bottle_orm::Error;
fn validate_age(age: i32) -> Result<(), Error> {
if age < 0 {
return Err(Error::InvalidData("Age must be non-negative".to_string()));
}
if age > 150 {
return Err(Error::InvalidData("Age seems unrealistic".to_string()));
}
Ok(())
}Variants§
InvalidData(String)
Invalid data error.
This variant is used when data validation fails before or after a database operation. It typically indicates business logic violations rather than database-level constraints.
§When to Use
- Data format validation (e.g., email format, phone number)
- Business rule violations (e.g., age limits, quantity constraints)
- Type conversion failures
- Serialization/deserialization errors
§Example
fn validate_email(email: &str) -> Result<(), Error> {
if !email.contains('@') {
return Err(Error::InvalidData(
format!("Invalid email format: {}", email)
));
}
Ok(())
}Conversion(String)
Type conversion error.
This variant is used when converting between Rust types and SQL types fails. It typically occurs during value binding or deserialization.
§When to Use
- Failed to parse string to DateTime, UUID, or numeric types
- Type mismatch during value binding
- Format conversion errors
§Example
fn parse_datetime(value: &str) -> Result<DateTime<Utc>, Error> {
value.parse::<DateTime<Utc>>()
.map_err(|e| Error::Conversion(format!("Failed to parse DateTime: {}", e)))
}DatabaseError(Error)
Database operation error.
This variant wraps errors from the underlying sqlx library.
It’s automatically converted from sqlx::Error via the #[from] attribute,
making error propagation seamless with the ? operator.
§Common Causes
- Connection Errors: Failed to connect to database, connection pool exhausted
- Query Errors: SQL syntax errors, table/column not found
- Constraint Violations: Primary key, foreign key, unique, not null violations
- Type Errors: Type mismatch between Rust and SQL types
- Row Not Found:
fetch_one()orfirst()found no matching rows
§Example
async fn get_user_by_id(db: &Database, id: i32) -> Result<User, Error> {
// sqlx::Error is automatically converted to Error::DatabaseError
let user = db.model::<User>()
.filter("id", "=", id)
.first()
.await?;
Ok(user)
}
// Handling specific database errors
match get_user_by_id(&db, 999).await {
Ok(user) => println!("Found: {:?}", user),
Err(Error::DatabaseError(e)) => {
if matches!(e, sqlx::Error::RowNotFound) {
eprintln!("User not found");
} else {
eprintln!("Database error: {}", e);
}
}
Err(e) => eprintln!("Other error: {}", e),
}InvalidArgument(String)
Invalid argument error.
This variant is used when method arguments fail validation. It indicates programmer error (passing invalid parameters) rather than runtime data issues.
§When to Use
- Negative values where only positive are allowed
- Out-of-range parameters (e.g., page number, limit)
- Invalid enum values or flags
- Null/empty values where required
§Example
impl QueryBuilder {
pub fn pagination(
mut self,
max_value: usize,
default: usize,
page: usize,
value: isize,
) -> Result<Self, Error> {
// Validate argument
if value < 0 {
return Err(Error::InvalidArgument(
"value cannot be negative".to_string()
));
}
// ... rest of implementation
Ok(self)
}
}Implementations§
Source§impl Error
Automatic conversion from sqlx::Error to Error::DatabaseError.
impl Error
Automatic conversion from sqlx::Error to Error::DatabaseError.
This is provided automatically by the #[from] attribute on the
DatabaseError variant. It enables using the ? operator to propagate
sqlx errors as Bottle ORM errors.
§Example
async fn example(db: &Database) -> Result<Vec<User>, Error> {
// sqlx::Error is automatically converted to Error via ?
let users = db.model::<User>().scan().await?;
Ok(users)
}Sourcepub fn invalid_data(msg: &str) -> Self
pub fn invalid_data(msg: &str) -> Self
Sourcepub fn invalid_argument(msg: &str) -> Self
pub fn invalid_argument(msg: &str) -> Self
Creates an InvalidArgument error from a string slice.
This is a convenience method to avoid calling .to_string() manually.
§Arguments
msg- The error message
§Example
fn set_limit(limit: isize) -> Result<(), Error> {
if limit < 0 {
return Err(Error::invalid_argument("Limit cannot be negative"));
}
Ok(())
}Sourcepub fn conversion(msg: &str) -> Self
pub fn conversion(msg: &str) -> Self
Trait Implementations§
Source§impl Error for Error
impl Error for Error
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
Auto Trait Implementations§
impl Freeze for Error
impl !RefUnwindSafe for Error
impl Send for Error
impl Sync for Error
impl Unpin for Error
impl !UnwindSafe for Error
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more