1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use crate::storage;
use crate::storage::kv::{Error as KvError, ErrorInner as KvErrorInner};
use crate::storage::mvcc::{Error as MvccError, ErrorInner as MvccErrorInner};
use crate::storage::txn::{Error as TxnError, ErrorInner as TxnErrorInner};
use error_code::{self, ErrorCode, ErrorCodeExt};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error("Region error (will back off and retry) {0:?}")]
Region(kvproto::errorpb::Error),
#[error("Key is locked (will clean up) {0:?}")]
Locked(kvproto::kvrpcpb::LockInfo),
#[error("Coprocessor task terminated due to exceeding the deadline")]
DeadlineExceeded,
#[error("Coprocessor task canceled due to exceeding max pending tasks")]
MaxPendingTasksExceeded,
#[error("{0}")]
Other(String),
}
impl From<Box<dyn std::error::Error + Send + Sync>> for Error {
#[inline]
fn from(err: Box<dyn std::error::Error + Send + Sync>) -> Self {
Error::Other(err.to_string())
}
}
impl From<Error> for tidb_query_common::error::StorageError {
fn from(err: Error) -> Self {
anyhow::Error::from(err).into()
}
}
impl From<tidb_query_common::error::StorageError> for Error {
fn from(err: tidb_query_common::error::StorageError) -> Self {
match err.0.downcast::<Error>() {
Ok(e) => e,
Err(e) => box_err!("Unknown storage error: {}", e),
}
}
}
impl From<tidb_query_common::error::EvaluateError> for Error {
fn from(err: tidb_query_common::error::EvaluateError) -> Self {
Error::Other(err.to_string())
}
}
impl From<tidb_query_common::Error> for Error {
fn from(err: tidb_query_common::Error) -> Self {
use tidb_query_common::error::ErrorInner;
match *err.0 {
ErrorInner::Storage(err) => err.into(),
ErrorInner::Evaluate(err) => err.into(),
}
}
}
impl From<KvError> for Error {
fn from(err: KvError) -> Self {
match err {
KvError(box KvErrorInner::Request(e)) => Error::Region(e),
e => Error::Other(e.to_string()),
}
}
}
impl From<MvccError> for Error {
fn from(err: MvccError) -> Self {
match err {
MvccError(box MvccErrorInner::KeyIsLocked(info)) => Error::Locked(info),
MvccError(box MvccErrorInner::Engine(engine_error)) => Error::from(engine_error),
e => Error::Other(e.to_string()),
}
}
}
impl From<TxnError> for Error {
fn from(err: storage::txn::Error) -> Self {
match err {
TxnError(box TxnErrorInner::Mvcc(mvcc_error)) => Error::from(mvcc_error),
TxnError(box TxnErrorInner::Engine(engine_error)) => Error::from(engine_error),
e => Error::Other(e.to_string()),
}
}
}
impl From<tikv_util::deadline::DeadlineError> for Error {
fn from(_: tikv_util::deadline::DeadlineError) -> Self {
Error::DeadlineExceeded
}
}
impl From<tidb_query_datatype::DataTypeError> for Error {
fn from(err: tidb_query_datatype::DataTypeError) -> Self {
Error::Other(err.to_string())
}
}
impl From<tidb_query_datatype::codec::Error> for Error {
fn from(err: tidb_query_datatype::codec::Error) -> Self {
Error::Other(err.to_string())
}
}
pub type Result<T> = std::result::Result<T, Error>;
impl ErrorCodeExt for Error {
fn error_code(&self) -> ErrorCode {
match self {
Error::Region(e) => e.error_code(),
Error::Locked(_) => error_code::coprocessor::LOCKED,
Error::DeadlineExceeded => error_code::coprocessor::DEADLINE_EXCEEDED,
Error::MaxPendingTasksExceeded => error_code::coprocessor::MAX_PENDING_TASKS_EXCEEDED,
Error::Other(_) => error_code::UNKNOWN,
}
}
}