use std::error; use std::fmt; use std::path::PathBuf; use std::str; use libc::c_int; use {ffi, errmsg_to_string}; /// Old name for `Error`. `SqliteError` is deprecated. pub type SqliteError = Error; #[derive(Debug)] pub enum Error { SqliteFailure(ffi::Error, Option), FromSqlConversionFailure(Box), Utf8Error(str::Utf8Error), NulError(::std::ffi::NulError), InvalidParameterName(String), InvalidPath(PathBuf), ExecuteReturnedResults, QueryReturnedNoRows, GetFromStaleRow, InvalidColumnIndex(c_int), InvalidColumnType, #[cfg(feature = "functions")] InvalidFunctionParameterType, #[cfg(feature = "functions")] #[allow(dead_code)] UserFunctionError(Box), } impl From for Error { fn from(err: str::Utf8Error) -> Error { Error::Utf8Error(err) } } impl From<::std::ffi::NulError> for Error { fn from(err: ::std::ffi::NulError) -> Error { Error::NulError(err) } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &Error::SqliteFailure(ref err, None) => err.fmt(f), &Error::SqliteFailure(_, Some(ref s)) => write!(f, "{}", s), &Error::FromSqlConversionFailure(ref err) => err.fmt(f), &Error::Utf8Error(ref err) => err.fmt(f), &Error::NulError(ref err) => err.fmt(f), &Error::InvalidParameterName(ref name) => write!(f, "Invalid parameter name: {}", name), &Error::InvalidPath(ref p) => write!(f, "Invalid path: {}", p.to_string_lossy()), &Error::ExecuteReturnedResults => write!(f, "Execute returned results - did you mean to call query?"), &Error::QueryReturnedNoRows => write!(f, "Query returned no rows"), &Error::GetFromStaleRow => write!(f, "Attempted to get a value from a stale row"), &Error::InvalidColumnIndex(i) => write!(f, "Invalid column index: {}", i), &Error::InvalidColumnType => write!(f, "Invalid column type"), #[cfg(feature = "functions")] &Error::InvalidFunctionParameterType => write!(f, "Invalid function parameter type"), #[cfg(feature = "functions")] &Error::UserFunctionError(ref err) => err.fmt(f), } } } impl error::Error for Error { fn description(&self) -> &str { match self { &Error::SqliteFailure(ref err, None) => err.description(), &Error::SqliteFailure(_, Some(ref s)) => s, &Error::FromSqlConversionFailure(ref err) => err.description(), &Error::Utf8Error(ref err) => err.description(), &Error::InvalidParameterName(_) => "invalid parameter name", &Error::NulError(ref err) => err.description(), &Error::InvalidPath(_) => "invalid path", &Error::ExecuteReturnedResults => "execute returned results - did you mean to call query?", &Error::QueryReturnedNoRows => "query returned no rows", &Error::GetFromStaleRow => "attempted to get a value from a stale row", &Error::InvalidColumnIndex(_) => "invalid column index", &Error::InvalidColumnType => "invalid column type", #[cfg(feature = "functions")] &Error::InvalidFunctionParameterType => "invalid function parameter type", #[cfg(feature = "functions")] &Error::UserFunctionError(ref err) => err.description(), } } fn cause(&self) -> Option<&error::Error> { match self { &Error::SqliteFailure(ref err, _) => Some(err), &Error::FromSqlConversionFailure(ref err) => Some(&**err), &Error::Utf8Error(ref err) => Some(err), &Error::NulError(ref err) => Some(err), &Error::InvalidParameterName(_) => None, &Error::InvalidPath(_) => None, &Error::ExecuteReturnedResults => None, &Error::QueryReturnedNoRows => None, &Error::GetFromStaleRow => None, &Error::InvalidColumnIndex(_) => None, &Error::InvalidColumnType => None, #[cfg(feature = "functions")] &Error::InvalidFunctionParameterType => None, #[cfg(feature = "functions")] &Error::UserFunctionError(ref err) => Some(&**err), } } } // These are public but not re-exported by lib.rs, so only visible within crate. pub fn error_from_sqlite_code(code: c_int, message: Option) -> Error { Error::SqliteFailure(ffi::Error::new(code), message) } pub fn error_from_handle(db: *mut ffi::Struct_sqlite3, code: c_int) -> Error { let message = if db.is_null() { None } else { Some(unsafe { errmsg_to_string(ffi::sqlite3_errmsg(db)) }) }; error_from_sqlite_code(code, message) }