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  }