github.com/datachainlab/burrow@v0.25.0/execution/errors/errors.go (about)

     1  package errors
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  type CodedError interface {
     8  	error
     9  	ErrorCode() Code
    10  	String() string
    11  }
    12  
    13  type Provider interface {
    14  	// Returns the an error if errors occurred some execution or nil if none occurred
    15  	Error() CodedError
    16  }
    17  
    18  type Sink interface {
    19  	PushError(error)
    20  }
    21  
    22  type Code uint32
    23  
    24  const (
    25  	ErrorCodeGeneric Code = iota
    26  	ErrorCodeUnknownAddress
    27  	ErrorCodeInsufficientBalance
    28  	ErrorCodeInvalidJumpDest
    29  	ErrorCodeInsufficientGas
    30  	ErrorCodeMemoryOutOfBounds
    31  	ErrorCodeCodeOutOfBounds
    32  	ErrorCodeInputOutOfBounds
    33  	ErrorCodeReturnDataOutOfBounds
    34  	ErrorCodeCallStackOverflow
    35  	ErrorCodeCallStackUnderflow
    36  	ErrorCodeDataStackOverflow
    37  	ErrorCodeDataStackUnderflow
    38  	ErrorCodeInvalidContract
    39  	ErrorCodeNativeContractCodeCopy
    40  	ErrorCodeExecutionAborted
    41  	ErrorCodeExecutionReverted
    42  	ErrorCodePermissionDenied
    43  	ErrorCodeNativeFunction
    44  	ErrorCodeEventPublish
    45  	ErrorCodeInvalidString
    46  	ErrorCodeEventMapping
    47  	ErrorCodeInvalidAddress
    48  	ErrorCodeDuplicateAddress
    49  	ErrorCodeInsufficientFunds
    50  	ErrorCodeOverpayment
    51  	ErrorCodeZeroPayment
    52  	ErrorCodeInvalidSequence
    53  	ErrorCodeReservedAddress
    54  	ErrorCodeIllegalWrite
    55  	ErrorCodeIntegerOverflow
    56  	ErrorCodeInvalidProposal
    57  	ErrorCodeExpiredProposal
    58  	ErrorCodeProposalExecuted
    59  	ErrorCodeNoInputPermission
    60  	ErrorCodeInvalidBlockNumber
    61  	ErrorCodeBlockNumberOutOfRange
    62  	ErrorCodeAlreadyVoted
    63  )
    64  
    65  func (c Code) ErrorCode() Code {
    66  	return c
    67  }
    68  
    69  func (c Code) Uint32() uint32 {
    70  	return uint32(c)
    71  }
    72  
    73  func (c Code) Error() string {
    74  	return fmt.Sprintf("Error %d: %s", c, c.String())
    75  }
    76  
    77  func (c Code) String() string {
    78  	switch c {
    79  	case ErrorCodeUnknownAddress:
    80  		return "unknown address"
    81  	case ErrorCodeInsufficientBalance:
    82  		return "insufficient balance"
    83  	case ErrorCodeInvalidJumpDest:
    84  		return "invalid jump dest"
    85  	case ErrorCodeInsufficientGas:
    86  		return "insufficient gas"
    87  	case ErrorCodeMemoryOutOfBounds:
    88  		return "memory out of bounds"
    89  	case ErrorCodeCodeOutOfBounds:
    90  		return "code out of bounds"
    91  	case ErrorCodeInputOutOfBounds:
    92  		return "input out of bounds"
    93  	case ErrorCodeReturnDataOutOfBounds:
    94  		return "return data out of bounds"
    95  	case ErrorCodeCallStackOverflow:
    96  		return "call stack overflow"
    97  	case ErrorCodeCallStackUnderflow:
    98  		return "call stack underflow"
    99  	case ErrorCodeDataStackOverflow:
   100  		return "data stack overflow"
   101  	case ErrorCodeDataStackUnderflow:
   102  		return "data stack underflow"
   103  	case ErrorCodeInvalidContract:
   104  		return "invalid contract"
   105  	case ErrorCodePermissionDenied:
   106  		return "permission denied"
   107  	case ErrorCodeNativeContractCodeCopy:
   108  		return "tried to copy native contract code"
   109  	case ErrorCodeExecutionAborted:
   110  		return "execution aborted"
   111  	case ErrorCodeExecutionReverted:
   112  		return "execution reverted"
   113  	case ErrorCodeNativeFunction:
   114  		return "native function error"
   115  	case ErrorCodeEventPublish:
   116  		return "event publish error"
   117  	case ErrorCodeInvalidString:
   118  		return "invalid string"
   119  	case ErrorCodeEventMapping:
   120  		return "event mapping error"
   121  	case ErrorCodeGeneric:
   122  		return "generic error"
   123  	case ErrorCodeInvalidAddress:
   124  		return "invalid address"
   125  	case ErrorCodeDuplicateAddress:
   126  		return "duplicate address"
   127  	case ErrorCodeInsufficientFunds:
   128  		return "insufficient funds"
   129  	case ErrorCodeOverpayment:
   130  		return "overpayment"
   131  	case ErrorCodeZeroPayment:
   132  		return "zero payment error"
   133  	case ErrorCodeInvalidSequence:
   134  		return "invalid sequence number"
   135  	case ErrorCodeReservedAddress:
   136  		return "address is reserved for SNative or internal use"
   137  	case ErrorCodeIllegalWrite:
   138  		return "callee attempted to illegally modify state"
   139  	case ErrorCodeIntegerOverflow:
   140  		return "integer overflow"
   141  	case ErrorCodeInvalidProposal:
   142  		return "proposal is invalid"
   143  	case ErrorCodeExpiredProposal:
   144  		return "proposal is expired since sequence number does not match"
   145  	case ErrorCodeProposalExecuted:
   146  		return "proposal has already been executed"
   147  	case ErrorCodeNoInputPermission:
   148  		return "account has no input permission"
   149  	case ErrorCodeInvalidBlockNumber:
   150  		return "invalid block number"
   151  	case ErrorCodeBlockNumberOutOfRange:
   152  		return "block number out of range"
   153  	case ErrorCodeAlreadyVoted:
   154  		return "vote already registered for this address"
   155  	default:
   156  		return "Unknown error"
   157  	}
   158  }
   159  
   160  func NewException(errorCode Code, exception string) *Exception {
   161  	if exception == "" {
   162  		return nil
   163  	}
   164  	return &Exception{
   165  		Code:      errorCode,
   166  		Exception: exception,
   167  	}
   168  }
   169  
   170  // Wraps any error as a Exception
   171  func AsException(err error) *Exception {
   172  	if err == nil {
   173  		return nil
   174  	}
   175  	switch e := err.(type) {
   176  	case *Exception:
   177  		return e
   178  	case CodedError:
   179  		return NewException(e.ErrorCode(), e.String())
   180  	default:
   181  		return NewException(ErrorCodeGeneric, err.Error())
   182  	}
   183  }
   184  
   185  func Wrap(err error, message string) *Exception {
   186  	ex := AsException(err)
   187  	return NewException(ex.ErrorCode(), message+": "+ex.Error())
   188  }
   189  
   190  func Errorf(format string, a ...interface{}) *Exception {
   191  	return ErrorCodef(ErrorCodeGeneric, format, a...)
   192  }
   193  
   194  func ErrorCodef(errorCode Code, format string, a ...interface{}) *Exception {
   195  	return NewException(errorCode, fmt.Sprintf(format, a...))
   196  }
   197  
   198  func (e *Exception) AsError() error {
   199  	// We need to return a bare untyped error here so that err == nil downstream
   200  	if e == nil {
   201  		return nil
   202  	}
   203  	return e
   204  }
   205  
   206  func (e *Exception) ErrorCode() Code {
   207  	return e.Code
   208  }
   209  
   210  func (e *Exception) Error() string {
   211  	return fmt.Sprintf("error %d - %s: %s", e.Code, e.Code.String(), e.Exception)
   212  }
   213  
   214  func (e *Exception) String() string {
   215  	if e == nil {
   216  		return ""
   217  	}
   218  	return e.Exception
   219  }
   220  
   221  func (e *Exception) Equal(ce CodedError) bool {
   222  	ex := AsException(ce)
   223  	if e == nil || ex == nil {
   224  		return e == nil && ex == nil
   225  	}
   226  	return e.Code == ex.Code && e.Exception == ex.Exception
   227  }
   228  
   229  type singleError struct {
   230  	CodedError
   231  }
   232  
   233  func FirstOnly() *singleError {
   234  	return &singleError{}
   235  }
   236  
   237  func (se *singleError) PushError(err error) {
   238  	if se.CodedError == nil {
   239  		// Do our nil dance
   240  		ex := AsException(err)
   241  		if ex != nil {
   242  			se.CodedError = ex
   243  		}
   244  	}
   245  }
   246  
   247  func (se *singleError) Error() CodedError {
   248  	return se.CodedError
   249  }
   250  
   251  func (se *singleError) Reset() {
   252  	se.CodedError = nil
   253  }