use std::result;
use thiserror::Error;
use crate::proto::kvrpcpb;
use crate::BoundRange;
#[derive(Debug, Error)]
#[allow(clippy::large_enum_variant)]
pub enum Error {
#[error("Unimplemented feature")]
Unimplemented,
#[error("Duplicate key insertion")]
DuplicateKeyInsertion,
#[error("Failed to resolve lock")]
ResolveLockError(Vec<kvrpcpb::LockInfo>),
#[error("Invalid operation for this type of transaction")]
InvalidTransactionType,
#[error("Cannot read or write data after any attempt to commit or roll back the transaction")]
OperationAfterCommitError,
#[error("1PC transaction could not be committed.")]
OnePcFailure,
#[error("transaction has no primary key")]
NoPrimaryKey,
#[error(
"The operation is not supported in current mode, please consider using RawClient with or without atomic mode"
)]
UnsupportedMode,
#[error("There is no current_regions in the EpochNotMatch error")]
NoCurrentRegions,
#[error("The specified entry is not found in the region cache")]
EntryNotFoundInRegionCache,
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("tokio channel error: {0}")]
Channel(#[from] tokio::sync::oneshot::error::RecvError),
#[error("gRPC error: {0}")]
Grpc(#[from] tonic::transport::Error),
#[error("gRPC api error: {0}")]
GrpcAPI(#[from] tonic::Status),
#[error("url error: {0}")]
Url(#[from] tonic::codegen::http::uri::InvalidUri),
#[error("A futures oneshot channel was canceled. {0}")]
Canceled(#[from] futures::channel::oneshot::Canceled),
#[error("Region error: {0:?}")]
RegionError(Box<crate::proto::errorpb::Error>),
#[error("Whether the transaction is committed or not is undetermined")]
UndeterminedError(Box<Error>),
#[error("{0:?}")]
KeyError(Box<crate::proto::kvrpcpb::KeyError>),
#[error("Multiple errors: {0:?}")]
ExtractedErrors(Vec<Error>),
#[error("Multiple key errors: {0:?}")]
MultipleKeyErrors(Vec<Error>),
#[error("Unsupported column family {}", _0)]
ColumnFamilyError(String),
#[error("Failed to join tokio tasks")]
JoinError(#[from] tokio::task::JoinError),
#[error("Region is not found for key: {:?}", key)]
RegionForKeyNotFound { key: Vec<u8> },
#[error("Region is not found for range: {:?}", range)]
RegionForRangeNotFound { range: BoundRange },
#[error("Region {} is not found in the response", region_id)]
RegionNotFoundInResponse { region_id: u64 },
#[error("Leader of region {} is not found", region_id)]
LeaderNotFound { region_id: u64 },
#[error("Limit {} exceeds max scan limit {}", limit, max_limit)]
MaxScanLimitExceeded { limit: u32, max_limit: u32 },
#[error("Invalid Semver string: {0:?}")]
InvalidSemver(#[from] semver::Error),
#[error("Kv error. {}", message)]
KvError { message: String },
#[error("{}", message)]
InternalError { message: String },
#[error("{0}")]
StringError(String),
#[error("PessimisticLock error: {:?}", inner)]
PessimisticLockError {
inner: Box<Error>,
success_keys: Vec<Vec<u8>>,
},
}
impl From<crate::proto::errorpb::Error> for Error {
fn from(e: crate::proto::errorpb::Error) -> Error {
Error::RegionError(Box::new(e))
}
}
impl From<crate::proto::kvrpcpb::KeyError> for Error {
fn from(e: crate::proto::kvrpcpb::KeyError) -> Error {
Error::KeyError(Box::new(e))
}
}
pub type Result<T> = result::Result<T, Error>;
#[doc(hidden)]
#[macro_export]
macro_rules! internal_err {
($e:expr) => ({
$crate::Error::InternalError {
message: format!("[{}:{}]: {}", file!(), line!(), $e)
}
});
($f:tt, $($arg:expr),+) => ({
internal_err!(format!($f, $($arg),+))
});
}