github.com/Finschia/finschia-sdk@v0.48.1/types/errors/errors.go (about)

     1  package errors
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  // RootCodespace is the codespace for all errors defined in this package
    11  const RootCodespace = "sdk"
    12  
    13  // UndefinedCodespace when we explicitly declare no codespace
    14  const UndefinedCodespace = "undefined"
    15  
    16  var (
    17  	// errInternal should never be exposed, but we reserve this code for non-specified errors
    18  	errInternal = Register(UndefinedCodespace, 1, "internal") //nolint:deadcode,unused,varcheck
    19  
    20  	// ErrTxDecode is returned if we cannot parse a transaction
    21  	ErrTxDecode = Register(RootCodespace, 2, "tx parse error")
    22  
    23  	// ErrInvalidSequence is used the sequence number (nonce) is incorrect
    24  	// for the signature
    25  	ErrInvalidSequence = Register(RootCodespace, 3, "invalid sequence")
    26  
    27  	// ErrUnauthorized is used whenever a request without sufficient
    28  	// authorization is handled.
    29  	ErrUnauthorized = Register(RootCodespace, 4, "unauthorized")
    30  
    31  	// ErrInsufficientFunds is used when the account cannot pay requested amount.
    32  	ErrInsufficientFunds = Register(RootCodespace, 5, "insufficient funds")
    33  
    34  	// ErrUnknownRequest to doc
    35  	ErrUnknownRequest = Register(RootCodespace, 6, "unknown request")
    36  
    37  	// ErrInvalidAddress to doc
    38  	ErrInvalidAddress = Register(RootCodespace, 7, "invalid address")
    39  
    40  	// ErrInvalidPubKey to doc
    41  	ErrInvalidPubKey = Register(RootCodespace, 8, "invalid pubkey")
    42  
    43  	// ErrUnknownAddress to doc
    44  	ErrUnknownAddress = Register(RootCodespace, 9, "unknown address")
    45  
    46  	// ErrInvalidCoins to doc
    47  	ErrInvalidCoins = Register(RootCodespace, 10, "invalid coins")
    48  
    49  	// ErrOutOfGas to doc
    50  	ErrOutOfGas = Register(RootCodespace, 11, "out of gas")
    51  
    52  	// ErrMemoTooLarge to doc
    53  	ErrMemoTooLarge = Register(RootCodespace, 12, "memo too large")
    54  
    55  	// ErrInsufficientFee to doc
    56  	ErrInsufficientFee = Register(RootCodespace, 13, "insufficient fee")
    57  
    58  	// ErrTooManySignatures to doc
    59  	ErrTooManySignatures = Register(RootCodespace, 14, "maximum number of signatures exceeded")
    60  
    61  	// ErrNoSignatures to doc
    62  	ErrNoSignatures = Register(RootCodespace, 15, "no signatures supplied")
    63  
    64  	// ErrJSONMarshal defines an ABCI typed JSON marshalling error
    65  	ErrJSONMarshal = Register(RootCodespace, 16, "failed to marshal JSON bytes")
    66  
    67  	// ErrJSONUnmarshal defines an ABCI typed JSON unmarshalling error
    68  	ErrJSONUnmarshal = Register(RootCodespace, 17, "failed to unmarshal JSON bytes")
    69  
    70  	// ErrInvalidRequest defines an ABCI typed error where the request contains
    71  	// invalid data.
    72  	ErrInvalidRequest = Register(RootCodespace, 18, "invalid request")
    73  
    74  	// ErrTxInMempoolCache defines an ABCI typed error where a tx already exists
    75  	// in the mempool.
    76  	ErrTxInMempoolCache = Register(RootCodespace, 19, "tx already in mempool")
    77  
    78  	// ErrMempoolIsFull defines an ABCI typed error where the mempool is full.
    79  	ErrMempoolIsFull = Register(RootCodespace, 20, "mempool is full")
    80  
    81  	// ErrTxTooLarge defines an ABCI typed error where tx is too large.
    82  	ErrTxTooLarge = Register(RootCodespace, 21, "tx too large")
    83  
    84  	// ErrKeyNotFound defines an error when the key doesn't exist
    85  	ErrKeyNotFound = Register(RootCodespace, 22, "key not found")
    86  
    87  	// ErrWrongPassword defines an error when the key password is invalid.
    88  	ErrWrongPassword = Register(RootCodespace, 23, "invalid account password")
    89  
    90  	// ErrorInvalidSigner defines an error when the tx intended signer does not match the given signer.
    91  	ErrorInvalidSigner = Register(RootCodespace, 24, "tx intended signer does not match the given signer")
    92  
    93  	// ErrorInvalidGasAdjustment defines an error for an invalid gas adjustment
    94  	ErrorInvalidGasAdjustment = Register(RootCodespace, 25, "invalid gas adjustment")
    95  
    96  	// ErrInvalidHeight defines an error for an invalid height
    97  	ErrInvalidHeight = Register(RootCodespace, 26, "invalid height")
    98  
    99  	// ErrInvalidVersion defines a general error for an invalid version
   100  	ErrInvalidVersion = Register(RootCodespace, 27, "invalid version")
   101  
   102  	// ErrInvalidChainID defines an error when the chain-id is invalid.
   103  	ErrInvalidChainID = Register(RootCodespace, 28, "invalid chain-id")
   104  
   105  	// ErrInvalidType defines an error an invalid type.
   106  	ErrInvalidType = Register(RootCodespace, 29, "invalid type")
   107  
   108  	// ErrTxTimeoutHeight defines an error for when a tx is rejected out due to an
   109  	// explicitly set timeout height.
   110  	ErrTxTimeoutHeight = Register(RootCodespace, 30, "tx timeout height")
   111  
   112  	// ErrUnknownExtensionOptions defines an error for unknown extension options.
   113  	ErrUnknownExtensionOptions = Register(RootCodespace, 31, "unknown extension options")
   114  
   115  	// ErrWrongSequence defines an error where the account sequence defined in
   116  	// the signer info doesn't match the account's actual sequence number.
   117  	ErrWrongSequence = Register(RootCodespace, 32, "incorrect account sequence")
   118  
   119  	// ErrPackAny defines an error when packing a protobuf message to Any fails.
   120  	ErrPackAny = Register(RootCodespace, 33, "failed packing protobuf message to Any")
   121  
   122  	// ErrUnpackAny defines an error when unpacking a protobuf message from Any fails.
   123  	ErrUnpackAny = Register(RootCodespace, 34, "failed unpacking protobuf message from Any")
   124  
   125  	// ErrLogic defines an internal logic error, e.g. an invariant or assertion
   126  	// that is violated. It is a programmer error, not a user-facing error.
   127  	ErrLogic = Register(RootCodespace, 35, "internal logic error")
   128  
   129  	// ErrConflict defines a conflict error, e.g. when two goroutines try to access
   130  	// the same resource and one of them fails.
   131  	ErrConflict = Register(RootCodespace, 36, "conflict")
   132  
   133  	// ErrNotSupported is returned when we call a branch of a code which is currently not
   134  	// supported.
   135  	ErrNotSupported = Register(RootCodespace, 37, "feature not supported")
   136  
   137  	// ErrNotFound defines an error when requested entity doesn't exist in the state.
   138  	ErrNotFound = Register(RootCodespace, 38, "not found")
   139  
   140  	// ErrIO should be used to wrap internal errors caused by external operation.
   141  	// Examples: not DB domain error, file writing etc...
   142  	ErrIO = Register(RootCodespace, 39, "Internal IO error")
   143  
   144  	// ErrAppConfig defines an error occurred if min-gas-prices field in BaseConfig is empty.
   145  	ErrAppConfig = Register(RootCodespace, 40, "error in app.toml")
   146  
   147  	// ErrPanic is only set when we recover from a panic, so we know to
   148  	// redact potentially sensitive system info
   149  	ErrPanic = Register(UndefinedCodespace, 111222, "panic")
   150  )
   151  
   152  // Register returns an error instance that should be used as the base for
   153  // creating error instances during runtime.
   154  //
   155  // Popular root errors are declared in this package, but extensions may want to
   156  // declare custom codes. This function ensures that no error code is used
   157  // twice. Attempt to reuse an error code results in panic.
   158  //
   159  // Use this function only during a program startup phase.
   160  func Register(codespace string, code uint32, description string) *Error {
   161  	// TODO - uniqueness is (codespace, code) combo
   162  	if e := getUsed(codespace, code); e != nil {
   163  		panic(fmt.Sprintf("error with code %d is already registered: %q", code, e.desc))
   164  	}
   165  
   166  	err := New(codespace, code, description)
   167  	setUsed(err)
   168  
   169  	return err
   170  }
   171  
   172  // usedCodes is keeping track of used codes to ensure their uniqueness. No two
   173  // error instances should share the same (codespace, code) tuple.
   174  var usedCodes = map[string]*Error{}
   175  
   176  func errorID(codespace string, code uint32) string {
   177  	return fmt.Sprintf("%s:%d", codespace, code)
   178  }
   179  
   180  func getUsed(codespace string, code uint32) *Error {
   181  	return usedCodes[errorID(codespace, code)]
   182  }
   183  
   184  func setUsed(err *Error) {
   185  	usedCodes[errorID(err.codespace, err.code)] = err
   186  }
   187  
   188  // ABCIError will resolve an error code/log from an abci result into
   189  // an error message. If the code is registered, it will map it back to
   190  // the canonical error, so we can do eg. ErrNotFound.Is(err) on something
   191  // we get back from an external API.
   192  //
   193  // This should *only* be used in clients, not in the server side.
   194  // The server (abci app / blockchain) should only refer to registered errors
   195  func ABCIError(codespace string, code uint32, log string) error {
   196  	if e := getUsed(codespace, code); e != nil {
   197  		return Wrap(e, log)
   198  	}
   199  	// This is a unique error, will never match on .Is()
   200  	// Use Wrap here to get a stack trace
   201  	return Wrap(New(codespace, code, "unknown"), log)
   202  }
   203  
   204  // Error represents a root error.
   205  //
   206  // Weave framework is using root error to categorize issues. Each instance
   207  // created during the runtime should wrap one of the declared root errors. This
   208  // allows error tests and returning all errors to the client in a safe manner.
   209  //
   210  // All popular root errors are declared in this package. If an extension has to
   211  // declare a custom root error, always use Register function to ensure
   212  // error code uniqueness.
   213  type Error struct {
   214  	codespace string
   215  	code      uint32
   216  	desc      string
   217  }
   218  
   219  func New(codespace string, code uint32, desc string) *Error {
   220  	return &Error{codespace: codespace, code: code, desc: desc}
   221  }
   222  
   223  func (e Error) Error() string {
   224  	return e.desc
   225  }
   226  
   227  func (e Error) ABCICode() uint32 {
   228  	return e.code
   229  }
   230  
   231  func (e Error) Codespace() string {
   232  	return e.codespace
   233  }
   234  
   235  // Is check if given error instance is of a given kind/type. This involves
   236  // unwrapping given error using the Cause method if available.
   237  func (e *Error) Is(err error) bool {
   238  	// Reflect usage is necessary to correctly compare with
   239  	// a nil implementation of an error.
   240  	if e == nil {
   241  		return isNilErr(err)
   242  	}
   243  
   244  	for {
   245  		if err == e {
   246  			return true
   247  		}
   248  
   249  		// If this is a collection of errors, this function must return
   250  		// true if at least one from the group match.
   251  		if u, ok := err.(unpacker); ok {
   252  			for _, er := range u.Unpack() {
   253  				if e.Is(er) {
   254  					return true
   255  				}
   256  			}
   257  		}
   258  
   259  		if c, ok := err.(causer); ok {
   260  			err = c.Cause()
   261  		} else {
   262  			return false
   263  		}
   264  	}
   265  }
   266  
   267  // Wrap extends this error with an additional information.
   268  // It's a handy function to call Wrap with sdk errors.
   269  func (e *Error) Wrap(desc string) error { return Wrap(e, desc) }
   270  
   271  // Wrapf extends this error with an additional information.
   272  // It's a handy function to call Wrapf with sdk errors.
   273  func (e *Error) Wrapf(desc string, args ...interface{}) error { return Wrapf(e, desc, args...) }
   274  
   275  func isNilErr(err error) bool {
   276  	// Reflect usage is necessary to correctly compare with
   277  	// a nil implementation of an error.
   278  	if err == nil {
   279  		return true
   280  	}
   281  	if reflect.ValueOf(err).Kind() == reflect.Struct {
   282  		return false
   283  	}
   284  	return reflect.ValueOf(err).IsNil()
   285  }
   286  
   287  // Wrap extends given error with an additional information.
   288  //
   289  // If the wrapped error does not provide ABCICode method (ie. stdlib errors),
   290  // it will be labeled as internal error.
   291  //
   292  // If err is nil, this returns nil, avoiding the need for an if statement when
   293  // wrapping a error returned at the end of a function
   294  func Wrap(err error, description string) error {
   295  	if err == nil {
   296  		return nil
   297  	}
   298  
   299  	// If this error does not carry the stacktrace information yet, attach
   300  	// one. This should be done only once per error at the lowest frame
   301  	// possible (most inner wrap).
   302  	if stackTrace(err) == nil {
   303  		err = errors.WithStack(err)
   304  	}
   305  
   306  	return &wrappedError{
   307  		parent: err,
   308  		msg:    description,
   309  	}
   310  }
   311  
   312  // Wrapf extends given error with an additional information.
   313  //
   314  // This function works like Wrap function with additional functionality of
   315  // formatting the input as specified.
   316  func Wrapf(err error, format string, args ...interface{}) error {
   317  	desc := fmt.Sprintf(format, args...)
   318  	return Wrap(err, desc)
   319  }
   320  
   321  type wrappedError struct {
   322  	// This error layer description.
   323  	msg string
   324  	// The underlying error that triggered this one.
   325  	parent error
   326  }
   327  
   328  func (e *wrappedError) Error() string {
   329  	return fmt.Sprintf("%s: %s", e.msg, e.parent.Error())
   330  }
   331  
   332  func (e *wrappedError) Cause() error {
   333  	return e.parent
   334  }
   335  
   336  // Is reports whether any error in e's chain matches a target.
   337  func (e *wrappedError) Is(target error) bool {
   338  	if e == target {
   339  		return true
   340  	}
   341  
   342  	w := e.Cause()
   343  	for {
   344  		if w == target {
   345  			return true
   346  		}
   347  
   348  		x, ok := w.(causer)
   349  		if ok {
   350  			w = x.Cause()
   351  		}
   352  		if x == nil {
   353  			return false
   354  		}
   355  	}
   356  }
   357  
   358  // Unwrap implements the built-in errors.Unwrap
   359  func (e *wrappedError) Unwrap() error {
   360  	return e.parent
   361  }
   362  
   363  // Recover captures a panic and stop its propagation. If panic happens it is
   364  // transformed into a ErrPanic instance and assigned to given error. Call this
   365  // function using defer in order to work as expected.
   366  func Recover(err *error) {
   367  	if r := recover(); r != nil {
   368  		*err = Wrapf(ErrPanic, "%v", r)
   369  	}
   370  }
   371  
   372  // WithType is a helper to augment an error with a corresponding type message
   373  func WithType(err error, obj interface{}) error {
   374  	return Wrap(err, fmt.Sprintf("%T", obj))
   375  }
   376  
   377  // IsOf checks if a received error is caused by one of the target errors.
   378  // It extends the errors.Is functionality to a list of errors.
   379  func IsOf(received error, targets ...error) bool {
   380  	for _, t := range targets {
   381  		if errors.Is(received, t) {
   382  			return true
   383  		}
   384  	}
   385  	return false
   386  }
   387  
   388  // causer is an interface implemented by an error that supports wrapping. Use
   389  // it to test if an error wraps another error instance.
   390  type causer interface {
   391  	Cause() error
   392  }
   393  
   394  type unpacker interface {
   395  	Unpack() []error
   396  }