cosmos-sdk/types/errors.go

205 lines
4.3 KiB
Go
Raw Normal View History

2018-01-18 00:25:23 -08:00
package types
import (
"fmt"
2018-01-26 04:19:33 -08:00
"runtime"
2018-01-18 00:25:23 -08:00
)
2018-02-04 16:59:11 -08:00
// ABCI Response Code
2018-01-26 06:22:56 -08:00
type CodeType uint32
2018-02-04 16:59:11 -08:00
// is everything okay?
2018-01-26 06:22:56 -08:00
func (code CodeType) IsOK() bool {
if code == CodeOK {
return true
}
2018-02-04 16:59:11 -08:00
return false
2018-01-26 06:22:56 -08:00
}
2018-02-04 16:59:11 -08:00
// ABCI Response Codes
// Base SDK reserves 0 ~ 99.
2018-01-18 00:25:23 -08:00
const (
2018-01-26 06:22:56 -08:00
CodeOK CodeType = 0
CodeInternal CodeType = 1
CodeTxParse CodeType = 2
2018-03-04 00:15:26 -08:00
CodeInvalidSequence CodeType = 3
2018-02-13 04:30:51 -08:00
CodeUnauthorized CodeType = 4
CodeInsufficientFunds CodeType = 5
CodeUnknownRequest CodeType = 6
CodeUnrecognizedAddress CodeType = 7
2018-03-17 11:54:18 -07:00
CodeInvalidPubKey CodeType = 8
2018-02-13 04:30:51 -08:00
CodeGenesisParse CodeType = 0xdead // TODO: remove ?
2018-01-18 00:25:23 -08:00
)
// NOTE: Don't stringer this, we'll put better messages in later.
2018-01-26 06:22:56 -08:00
func CodeToDefaultMsg(code CodeType) string {
2018-01-18 00:25:23 -08:00
switch code {
2018-01-26 04:19:33 -08:00
case CodeInternal:
2018-01-18 00:25:23 -08:00
return "Internal error"
2018-01-26 04:19:33 -08:00
case CodeTxParse:
2018-01-18 00:25:23 -08:00
return "Tx parse error"
2018-02-06 19:23:30 -08:00
case CodeGenesisParse:
return "Genesis parse error"
2018-03-04 00:15:26 -08:00
case CodeInvalidSequence:
return "Invalid sequence"
2018-01-18 00:25:23 -08:00
case CodeUnauthorized:
return "Unauthorized"
case CodeInsufficientFunds:
return "Insufficent funds"
case CodeUnknownRequest:
return "Unknown request"
case CodeUnrecognizedAddress:
return "Unrecognized address"
2018-03-17 11:54:18 -07:00
case CodeInvalidPubKey:
2018-03-17 13:53:27 -07:00
return "Invalid pubkey"
2018-01-18 00:25:23 -08:00
default:
return fmt.Sprintf("Unknown code %d", code)
}
}
//--------------------------------------------------------------------------------
// All errors are created via constructors so as to enable us to hijack them
// and inject stack traces if we really want to.
2018-02-04 16:59:11 -08:00
// nolint
2018-01-26 04:19:33 -08:00
func ErrInternal(msg string) Error {
return newError(CodeInternal, msg)
2018-01-18 00:25:23 -08:00
}
2018-01-26 04:19:33 -08:00
func ErrTxParse(msg string) Error {
return newError(CodeTxParse, msg)
2018-01-18 00:25:23 -08:00
}
2018-02-06 19:23:30 -08:00
func ErrGenesisParse(msg string) Error {
return newError(CodeGenesisParse, msg)
}
2018-03-04 00:15:26 -08:00
func ErrInvalidSequence(msg string) Error {
return newError(CodeInvalidSequence, msg)
2018-01-18 00:25:23 -08:00
}
2018-01-26 04:19:33 -08:00
func ErrUnauthorized(msg string) Error {
return newError(CodeUnauthorized, msg)
2018-01-18 00:25:23 -08:00
}
2018-01-26 04:19:33 -08:00
func ErrInsufficientFunds(msg string) Error {
return newError(CodeInsufficientFunds, msg)
2018-01-18 00:25:23 -08:00
}
2018-01-26 04:19:33 -08:00
func ErrUnknownRequest(msg string) Error {
return newError(CodeUnknownRequest, msg)
2018-01-18 00:25:23 -08:00
}
2018-03-17 11:54:18 -07:00
func ErrUnrecognizedAddress(msg string) Error {
return newError(CodeUnrecognizedAddress, msg)
2018-01-26 04:19:33 -08:00
}
2018-03-17 11:54:18 -07:00
func ErrInvalidPubKey(msg string) Error {
return newError(CodeInvalidPubKey, msg)
2018-03-14 10:16:52 -07:00
}
2018-01-18 00:25:23 -08:00
//----------------------------------------
// Error & sdkError
2018-02-04 16:59:11 -08:00
// sdk Error type
2018-01-18 00:25:23 -08:00
type Error interface {
Error() string
2018-01-26 06:22:56 -08:00
ABCICode() CodeType
2018-01-18 00:25:23 -08:00
ABCILog() string
Trace(msg string) Error
TraceCause(cause error, msg string) Error
Cause() error
Result() Result
}
2018-01-26 06:22:56 -08:00
func NewError(code CodeType, msg string) Error {
2018-01-26 04:19:33 -08:00
return newError(code, msg)
2018-01-18 00:25:23 -08:00
}
type traceItem struct {
msg string
filename string
lineno int
}
2018-01-26 04:19:33 -08:00
func (ti traceItem) String() string {
return fmt.Sprintf("%v:%v %v", ti.filename, ti.lineno, ti.msg)
}
2018-01-18 00:25:23 -08:00
type sdkError struct {
2018-01-26 06:22:56 -08:00
code CodeType
msg string
cause error
traces []traceItem
2018-01-18 00:25:23 -08:00
}
2018-01-26 06:22:56 -08:00
func newError(code CodeType, msg string) *sdkError {
2018-01-18 00:25:23 -08:00
// TODO capture stacktrace if ENV is set.
2018-01-26 04:19:33 -08:00
if msg == "" {
msg = CodeToDefaultMsg(code)
2018-01-18 00:25:23 -08:00
}
return &sdkError{
2018-01-26 06:22:56 -08:00
code: code,
msg: msg,
cause: nil,
traces: nil,
2018-01-18 00:25:23 -08:00
}
}
// Implements ABCIError.
func (err *sdkError) Error() string {
2018-01-26 06:22:56 -08:00
return fmt.Sprintf("Error{%d:%s,%v,%v}", err.code, err.msg, err.cause, len(err.traces))
2018-01-18 00:25:23 -08:00
}
// Implements ABCIError.
2018-01-26 06:22:56 -08:00
func (err *sdkError) ABCICode() CodeType {
2018-01-18 00:25:23 -08:00
return err.code
}
// Implements ABCIError.
func (err *sdkError) ABCILog() string {
2018-01-26 04:19:33 -08:00
traceLog := ""
2018-01-26 06:22:56 -08:00
for _, ti := range err.traces {
2018-01-26 04:19:33 -08:00
traceLog += ti.String() + "\n"
}
return fmt.Sprintf("msg: %v\ntrace:\n%v",
err.msg,
traceLog,
)
2018-01-18 00:25:23 -08:00
}
2018-01-26 04:19:33 -08:00
// Add tracing information with msg.
2018-01-18 00:25:23 -08:00
func (err *sdkError) Trace(msg string) Error {
2018-01-26 06:22:56 -08:00
return err.doTrace(msg, 2)
}
// Add tracing information with cause and msg.
func (err *sdkError) TraceCause(cause error, msg string) Error {
err.cause = cause
return err.doTrace(msg, 2)
}
func (err *sdkError) doTrace(msg string, n int) Error {
_, fn, line, ok := runtime.Caller(n)
2018-01-26 04:19:33 -08:00
if !ok {
if fn == "" {
fn = "<unknown>"
}
if line <= 0 {
line = -1
}
}
// Include file & line number & msg.
2018-01-18 00:25:23 -08:00
// Do not include the whole stack trace.
2018-01-26 06:22:56 -08:00
err.traces = append(err.traces, traceItem{
2018-01-26 04:19:33 -08:00
filename: fn,
lineno: line,
2018-01-18 00:25:23 -08:00
msg: msg,
})
return err
}
func (err *sdkError) Cause() error {
return err.cause
}
func (err *sdkError) Result() Result {
return Result{
Code: err.ABCICode(),
Log: err.ABCILog(),
}
}