github.com/KinWaiYuen/client-go/v2@v2.5.4/error/error.go (about) 1 // Copyright 2021 TiKV Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // NOTE: The code in this file is based on code from the 16 // TiDB project, licensed under the Apache License v 2.0 17 // 18 // https://github.com/pingcap/tidb/tree/cc5e161ac06827589c4966674597c137cc9e809c/store/tikv/error/error.go 19 // 20 21 // Copyright 2016 PingCAP, Inc. 22 // 23 // Licensed under the Apache License, Version 2.0 (the "License"); 24 // you may not use this file except in compliance with the License. 25 // You may obtain a copy of the License at 26 // 27 // http://www.apache.org/licenses/LICENSE-2.0 28 // 29 // Unless required by applicable law or agreed to in writing, software 30 // distributed under the License is distributed on an "AS IS" BASIS, 31 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 32 // See the License for the specific language governing permissions and 33 // limitations under the License. 34 35 package error 36 37 import ( 38 "fmt" 39 "time" 40 41 "github.com/KinWaiYuen/client-go/v2/internal/logutil" 42 "github.com/KinWaiYuen/client-go/v2/util" 43 "github.com/pingcap/errors" 44 "github.com/pingcap/kvproto/pkg/kvrpcpb" 45 "github.com/pingcap/kvproto/pkg/pdpb" 46 "github.com/pingcap/parser/terror" 47 "go.uber.org/zap" 48 ) 49 50 var ( 51 // ErrBodyMissing response body is missing error 52 ErrBodyMissing = errors.New("response body is missing") 53 // ErrTiDBShuttingDown is returned when TiDB is closing and send request to tikv fail, do not retry. 54 ErrTiDBShuttingDown = errors.New("tidb server shutting down") 55 // ErrNotExist means the related data not exist. 56 ErrNotExist = errors.New("not exist") 57 // ErrCannotSetNilValue is the error when sets an empty value. 58 ErrCannotSetNilValue = errors.New("can not set nil value") 59 // ErrInvalidTxn is the error when commits or rollbacks in an invalid transaction. 60 ErrInvalidTxn = errors.New("invalid transaction") 61 // ErrTiKVServerTimeout is the error when tikv server is timeout. 62 ErrTiKVServerTimeout = errors.New("tikv server timeout") 63 // ErrTiFlashServerTimeout is the error when tiflash server is timeout. 64 ErrTiFlashServerTimeout = errors.New("tiflash server timeout") 65 // ErrQueryInterrupted is the error when the query is interrupted. 66 ErrQueryInterrupted = errors.New("query interruppted") 67 // ErrTiKVStaleCommand is the error that the command is stale in tikv. 68 ErrTiKVStaleCommand = errors.New("tikv stale command") 69 // ErrTiKVMaxTimestampNotSynced is the error that tikv's max timestamp is not synced. 70 ErrTiKVMaxTimestampNotSynced = errors.New("tikv max timestamp not synced") 71 // ErrLockAcquireFailAndNoWaitSet is the error that acquire the lock failed while no wait is setted. 72 ErrLockAcquireFailAndNoWaitSet = errors.New("lock acquired failed and no wait is setted") 73 // ErrResolveLockTimeout is the error that resolve lock timeout. 74 ErrResolveLockTimeout = errors.New("resolve lock timeout") 75 // ErrLockWaitTimeout is the error that wait for the lock is timeout. 76 ErrLockWaitTimeout = errors.New("lock wait timeout") 77 // ErrTiKVServerBusy is the error when tikv server is busy. 78 ErrTiKVServerBusy = errors.New("tikv server busy") 79 // ErrTiFlashServerBusy is the error that tiflash server is busy. 80 ErrTiFlashServerBusy = errors.New("tiflash server busy") 81 // ErrRegionUnavailable is the error when region is not available. 82 ErrRegionUnavailable = errors.New("region unavailable") 83 // ErrRegionDataNotReady is the error when region's data is not ready when querying it with safe_ts 84 ErrRegionDataNotReady = errors.New("region data not ready") 85 // ErrRegionNotInitialized is error when region is not initialized 86 ErrRegionNotInitialized = errors.New("region not Initialized") 87 // ErrTiKVDiskFull is the error when tikv server disk usage is full. 88 ErrTiKVDiskFull = errors.New("tikv disk full") 89 // ErrUnknown is the unknow error. 90 ErrUnknown = errors.New("unknow") 91 ) 92 93 // MismatchClusterID represents the message that the cluster ID of the PD client does not match the PD. 94 const MismatchClusterID = "mismatch cluster id" 95 96 // IsErrNotFound checks if err is a kind of NotFound error. 97 func IsErrNotFound(err error) bool { 98 return errors.ErrorEqual(err, ErrNotExist) 99 } 100 101 // ErrDeadlock wraps *kvrpcpb.Deadlock to implement the error interface. 102 // It also marks if the deadlock is retryable. 103 type ErrDeadlock struct { 104 *kvrpcpb.Deadlock 105 IsRetryable bool 106 } 107 108 func (d *ErrDeadlock) Error() string { 109 return d.Deadlock.String() 110 } 111 112 // PDError wraps *pdpb.Error to implement the error interface. 113 type PDError struct { 114 Err *pdpb.Error 115 } 116 117 func (d *PDError) Error() string { 118 return d.Err.String() 119 } 120 121 // ErrKeyExist wraps *pdpb.AlreadyExist to implement the error interface. 122 type ErrKeyExist struct { 123 *kvrpcpb.AlreadyExist 124 } 125 126 func (k *ErrKeyExist) Error() string { 127 return k.AlreadyExist.String() 128 } 129 130 // IsErrKeyExist returns true if it is ErrKeyExist. 131 func IsErrKeyExist(err error) bool { 132 _, ok := errors.Cause(err).(*ErrKeyExist) 133 return ok 134 } 135 136 // ErrWriteConflict wraps *kvrpcpb.ErrWriteConflict to implement the error interface. 137 type ErrWriteConflict struct { 138 *kvrpcpb.WriteConflict 139 } 140 141 func (k *ErrWriteConflict) Error() string { 142 return fmt.Sprintf("write conflict { %s }", k.WriteConflict.String()) 143 } 144 145 // IsErrWriteConflict returns true if it is ErrWriteConflict. 146 func IsErrWriteConflict(err error) bool { 147 _, ok := errors.Cause(err).(*ErrWriteConflict) 148 return ok 149 } 150 151 //NewErrWriteConfictWithArgs generates an ErrWriteConflict with args. 152 func NewErrWriteConfictWithArgs(startTs, conflictTs, conflictCommitTs uint64, key []byte) *ErrWriteConflict { 153 conflict := kvrpcpb.WriteConflict{ 154 StartTs: startTs, 155 ConflictTs: conflictTs, 156 Key: key, 157 ConflictCommitTs: conflictCommitTs, 158 } 159 return &ErrWriteConflict{WriteConflict: &conflict} 160 } 161 162 // ErrWriteConflictInLatch is the error when the commit meets an write conflict error when local latch is enabled. 163 type ErrWriteConflictInLatch struct { 164 StartTS uint64 165 } 166 167 func (e *ErrWriteConflictInLatch) Error() string { 168 return fmt.Sprintf("write conflict in latch,startTS: %v", e.StartTS) 169 } 170 171 // ErrRetryable wraps *kvrpcpb.Retryable to implement the error interface. 172 type ErrRetryable struct { 173 Retryable string 174 } 175 176 func (k *ErrRetryable) Error() string { 177 return k.Retryable 178 } 179 180 // ErrTxnTooLarge is the error when transaction is too large, lock time reached the maximum value. 181 type ErrTxnTooLarge struct { 182 Size int 183 } 184 185 func (e *ErrTxnTooLarge) Error() string { 186 return fmt.Sprintf("txn too large, size: %v.", e.Size) 187 } 188 189 // ErrEntryTooLarge is the error when a key value entry is too large. 190 type ErrEntryTooLarge struct { 191 Limit uint64 192 Size uint64 193 } 194 195 func (e *ErrEntryTooLarge) Error() string { 196 return fmt.Sprintf("entry size too large, size: %v,limit: %v.", e.Size, e.Limit) 197 } 198 199 // ErrPDServerTimeout is the error when pd server is timeout. 200 type ErrPDServerTimeout struct { 201 msg string 202 } 203 204 // NewErrPDServerTimeout creates an ErrPDServerTimeout. 205 func NewErrPDServerTimeout(msg string) error { 206 return &ErrPDServerTimeout{msg} 207 } 208 209 func (e *ErrPDServerTimeout) Error() string { 210 return e.msg 211 } 212 213 // ErrGCTooEarly is the error that GC life time is shorter than transaction duration 214 type ErrGCTooEarly struct { 215 TxnStartTS time.Time 216 GCSafePoint time.Time 217 } 218 219 func (e *ErrGCTooEarly) Error() string { 220 return fmt.Sprintf("GC life time is shorter than transaction duration, transaction starts at %v, GC safe point is %v", e.TxnStartTS, e.GCSafePoint) 221 } 222 223 // ErrTokenLimit is the error that token is up to the limit. 224 type ErrTokenLimit struct { 225 StoreID uint64 226 } 227 228 func (e *ErrTokenLimit) Error() string { 229 return fmt.Sprintf("Store token is up to the limit, store id = %d.", e.StoreID) 230 } 231 232 // ExtractKeyErr extracts a KeyError. 233 func ExtractKeyErr(keyErr *kvrpcpb.KeyError) error { 234 if val, err := util.EvalFailpoint("mockRetryableErrorResp"); err == nil { 235 if val.(bool) { 236 keyErr.Conflict = nil 237 keyErr.Retryable = "mock retryable error" 238 } 239 } 240 241 if keyErr.Conflict != nil { 242 return &ErrWriteConflict{WriteConflict: keyErr.GetConflict()} 243 } 244 245 if keyErr.Retryable != "" { 246 return &ErrRetryable{Retryable: keyErr.Retryable} 247 } 248 249 if keyErr.Abort != "" { 250 err := errors.Errorf("tikv aborts txn: %s", keyErr.GetAbort()) 251 logutil.BgLogger().Warn("2PC failed", zap.Error(err)) 252 return errors.Trace(err) 253 } 254 if keyErr.CommitTsTooLarge != nil { 255 err := errors.Errorf("commit TS %v is too large", keyErr.CommitTsTooLarge.CommitTs) 256 logutil.BgLogger().Warn("2PC failed", zap.Error(err)) 257 return errors.Trace(err) 258 } 259 if keyErr.TxnNotFound != nil { 260 err := errors.Errorf("txn %d not found", keyErr.TxnNotFound.StartTs) 261 return errors.Trace(err) 262 } 263 return errors.Errorf("unexpected KeyError: %s", keyErr.String()) 264 } 265 266 // IsErrorUndetermined checks if the error is undetermined error. 267 func IsErrorUndetermined(err error) bool { 268 return terror.ErrorEqual(err, terror.ErrResultUndetermined) 269 }