Skip to main content

tikv_client/common/
errors.rs

1// Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0.
2
3use std::result;
4
5use thiserror::Error;
6
7use crate::proto::kvrpcpb;
8use crate::region::RegionVerId;
9use crate::BoundRange;
10
11/// Protobuf-generated region-level error returned by TiKV.
12///
13/// This type is generated from TiKV's protobuf definitions and may change in a
14/// future release even if the wire format is compatible.
15#[doc(inline)]
16pub use crate::proto::errorpb::Error as ProtoRegionError;
17
18/// Protobuf-generated per-key error returned by TiKV.
19///
20/// This type is generated from TiKV's protobuf definitions and may change in a
21/// future release even if the wire format is compatible.
22#[doc(inline)]
23pub use crate::proto::kvrpcpb::KeyError as ProtoKeyError;
24
25/// An error originating from the TiKV client or dependencies.
26#[derive(Debug, Error)]
27#[allow(clippy::large_enum_variant)]
28pub enum Error {
29    /// Feature is not implemented.
30    #[error("Unimplemented feature")]
31    Unimplemented,
32    /// Duplicate key insertion happens.
33    #[error("Duplicate key insertion")]
34    DuplicateKeyInsertion,
35    /// Failed to resolve a lock
36    #[error("Failed to resolve lock")]
37    ResolveLockError(Vec<kvrpcpb::LockInfo>),
38    /// Will raise this error when using a pessimistic txn only operation on an optimistic txn
39    #[error("Invalid operation for this type of transaction")]
40    InvalidTransactionType,
41    /// It's not allowed to perform operations in a transaction after it has been committed or rolled back.
42    #[error("Cannot read or write data after any attempt to commit or roll back the transaction")]
43    OperationAfterCommitError,
44    /// We tried to use 1pc for a transaction, but it didn't work. Probably should have used 2pc.
45    #[error("1PC transaction could not be committed.")]
46    OnePcFailure,
47    /// An operation requires a primary key, but the transaction was empty.
48    #[error("transaction has no primary key")]
49    NoPrimaryKey,
50    /// For raw client, operation is not supported in atomic/non-atomic mode.
51    #[error(
52        "The operation is not supported in current mode, please consider using RawClient with or without atomic mode"
53    )]
54    UnsupportedMode,
55    #[error("There is no current_regions in the EpochNotMatch error")]
56    NoCurrentRegions,
57    #[error("The specified entry is not found in the region cache")]
58    EntryNotFoundInRegionCache,
59    /// Wraps a `std::io::Error`.
60    #[error("IO error: {0}")]
61    Io(#[from] std::io::Error),
62    /// Wraps a `std::io::Error`.
63    #[error("tokio channel error: {0}")]
64    Channel(#[from] tokio::sync::oneshot::error::RecvError),
65    /// Wraps a `grpcio::Error`.
66    #[error("gRPC error: {0}")]
67    Grpc(#[from] tonic::transport::Error),
68    /// Wraps a `reqwest::Error`.
69    /// Wraps a `grpcio::Error`.
70    #[error("gRPC api error: {0}")]
71    GrpcAPI(#[from] tonic::Status),
72    /// Wraps a `grpcio::Error`.
73    #[error("url error: {0}")]
74    Url(#[from] tonic::codegen::http::uri::InvalidUri),
75    /// Represents that a futures oneshot channel was cancelled.
76    #[error("A futures oneshot channel was canceled. {0}")]
77    Canceled(#[from] futures::channel::oneshot::Canceled),
78    /// Errors caused by changes of region information
79    #[error("Region error: {0:?}")]
80    RegionError(Box<ProtoRegionError>),
81    /// Whether the transaction is committed or not is undetermined
82    #[error("Whether the transaction is committed or not is undetermined")]
83    UndeterminedError(Box<Error>),
84    /// Wraps a per-key error returned by TiKV.
85    #[error("{0:?}")]
86    KeyError(Box<ProtoKeyError>),
87    /// Multiple errors generated from the ExtractError plan.
88    #[error("Multiple errors: {0:?}")]
89    ExtractedErrors(Vec<Error>),
90    /// Multiple key errors
91    #[error("Multiple key errors: {0:?}")]
92    MultipleKeyErrors(Vec<Error>),
93    /// Invalid ColumnFamily
94    #[error("Unsupported column family {}", _0)]
95    ColumnFamilyError(String),
96    /// Can't join tokio tasks
97    #[error("Failed to join tokio tasks")]
98    JoinError(#[from] tokio::task::JoinError),
99    /// No region is found for the given key.
100    #[error("Region is not found for key: {:?}", key)]
101    RegionForKeyNotFound { key: Vec<u8> },
102    #[error("Region is not found for range: {:?}", range)]
103    RegionForRangeNotFound { range: BoundRange },
104    /// No region is found for the given id. note: distinguish it with the RegionNotFound error in errorpb.
105    #[error("Region {} is not found in the response", region_id)]
106    RegionNotFoundInResponse { region_id: u64 },
107    /// No leader is found for the given id.
108    #[error("Leader of region {} is not found", region.id)]
109    LeaderNotFound { region: RegionVerId },
110    /// Scan limit exceeds the maximum
111    #[error("Limit {} exceeds max scan limit {}", limit, max_limit)]
112    MaxScanLimitExceeded { limit: u32, max_limit: u32 },
113    #[error("Invalid Semver string: {0:?}")]
114    InvalidSemver(#[from] semver::Error),
115    /// A string error returned by TiKV server
116    #[error("Kv error. {}", message)]
117    KvError { message: String },
118    #[error("{}", message)]
119    InternalError { message: String },
120    #[error("{0}")]
121    StringError(String),
122    #[error("PessimisticLock error: {:?}", inner)]
123    PessimisticLockError {
124        inner: Box<Error>,
125        success_keys: Vec<Vec<u8>>,
126    },
127    #[error("Keyspace not found: {0}")]
128    KeyspaceNotFound(String),
129    #[error("Transaction not found error: {:?}", _0)]
130    TxnNotFound(kvrpcpb::TxnNotFound),
131}
132
133impl From<ProtoRegionError> for Error {
134    fn from(e: ProtoRegionError) -> Error {
135        Error::RegionError(Box::new(e))
136    }
137}
138
139impl From<ProtoKeyError> for Error {
140    fn from(e: ProtoKeyError) -> Error {
141        Error::KeyError(Box::new(e))
142    }
143}
144
145/// A result holding an [`Error`](enum@Error).
146pub type Result<T> = result::Result<T, Error>;
147
148#[doc(hidden)]
149#[macro_export]
150macro_rules! internal_err {
151    ($e:expr) => ({
152        $crate::Error::InternalError {
153            message: format!("[{}:{}]: {}", file!(), line!(),  $e)
154        }
155    });
156    ($f:tt, $($arg:expr),+) => ({
157        internal_err!(format!($f, $($arg),+))
158    });
159}