Error

Enum Error 

Source
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 errors
  • DatabaseError - Wrapped sqlx database errors
  • InvalidArgument - 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() or first() 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.

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)
}
Source

pub fn invalid_data(msg: &str) -> Self

Creates an InvalidData error from a string slice.

This is a convenience method to avoid calling .to_string() manually.

§Arguments
  • msg - The error message
§Example
fn validate(value: i32) -> Result<(), Error> {
    if value < 0 {
        return Err(Error::invalid_data("Value must be positive"));
    }
    Ok(())
}
Source

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(())
}
Source

pub fn conversion(msg: &str) -> Self

Creates a Conversion error from a string slice.

This is a convenience method to avoid calling .to_string() manually.

§Arguments
  • msg - The error message
§Example
fn parse_value(value: &str) -> Result<i32, Error> {
    value.parse::<i32>()
        .map_err(|_| Error::conversion("Invalid integer format"))
}

Trait Implementations§

Source§

impl Debug for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Error

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for Error

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for Error

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more