Documentation ¶
Overview ¶
Package errors implements a basic error wrapping pattern, so that errors can be annotated with additional information without losing the original error.
Example:
import "chain/errors" func query() error { err := pq.Exec("SELECT...") if err != nil { return errors.Wrap(err, "select query failed") } err = pq.Exec("INSERT...") if err != nil { return errors.Wrap(err, "insert query failed") } return nil } func main() { err := query() if _, ok := errors.Root(err).(sql.ErrNoRows); ok { log.Println("There were no results") return } else if err != nil { log.Println(err) return } log.Println("success") }
When to wrap errors ¶
Errors should be wrapped with additional messages when the context is ambiguous. This includes when the error could arise in multiple locations in the same function, when the error is very common and likely to appear at different points in the call tree (e.g., JSON serialization errors), or when you need specific parameters alongside the original error message.
Error handling best practices ¶
Errors are part of a function's interface. If you expect the caller to perform conditional error handling, you should document the errors returned by your function in a function comment, and include it as part of your unit tests.
Be disciplined about validating user input. Programs should draw a very clear distinction between user errors and internal errors.
Avoid redundant error logging. If you return an error, assume it will be logged higher up the call stack. For a given project, choose an appropriate layer to handle error logging.
Index ¶
- Constants
- Variables
- func Data(err error) map[string]interface{}
- func Detail(err error) string
- func New(text string) error
- func Root(e error) error
- func Sub(root, err error) error
- func WithData(err error, keyval ...interface{}) error
- func WithDetail(err error, text string) error
- func WithDetailf(err error, format string, v ...interface{}) error
- func Wrap(err error, a ...interface{}) error
- func Wrapf(err error, format string, a ...interface{}) error
- type StackFrame
- type Writer
Constants ¶
const ( // transaction err ErrAPINoTxInfo = 1101 ErrAPINoTxOut = 1102 ErrAPIRawTx = 1103 ErrAPIDuplicateTx = 1104 ErrAPIInsufficient = 1105 ErrAPIFailedToMaxwell = 1106 ErrAPIFindingUtxo = 1107 ErrAPIFindingBalance = 1108 ErrAPIEstimateTxFee = 1109 // block err ErrAPINewestHash = 1201 ErrAPIBlockNotFound = 1202 ErrAPINextBlock = 1203 ErrAPIBlockHashByHeight = 1204 ErrAPIBlockHeaderNotFound = 1205 // wallet err ErrAPIWalletInternal = 1301 ErrAPICreateRedeemScript = 1302 ErrAPICreatePubKey = 1303 ErrAPINoAddressInWallet = 1304 ErrAPICreateAddress = 1305 ErrAPINoPrivKeyByPubKey = 1306 ErrAPINoScriptByAddress = 1307 ErrAPINoSeedsInWallet = 1310 // txScript ErrAPICreatePkScript = 1401 ErrAPISignTx = 1402 ErrAPINewEngine = 1403 ErrAPIExecute = 1404 ErrAPIRejectTx = 1405 ErrAPIExtractPKScript = 1406 // Invalid Parameter ErrAPIInvalidParameter = 1501 ErrAPIInvalidLockTime = 1502 ErrAPIInvalidAmount = 1503 ErrAPIInvalidAddress = 1504 ErrAPIInvalidFlag = 1505 ErrAPIInvalidIndex = 1506 // Decode, Encode and deserialize err ErrAPIFailedDecodeAddress = 1601 ErrAPIDecodeHexString = 1602 ErrAPIShaHashFromStr = 1603 ErrAPIEncode = 1604 ErrAPIDeserialization = 1605 ErrAPIDecodePrivKey = 1606 ErrAPIDisasmScript = 1607 // other err ErrAPIUnknownErr = 1701 ErrAPINet = 1702 ErrNoMinningAddrress = 1703 )
Variables ¶
var ErrCode = map[uint32]string{ ErrAPINoTxInfo: "No information available about transaction", ErrAPIInvalidIndex: "Invalid OutPoint index", ErrAPINoTxOut: "Invalid preOutPoint", ErrAPIDuplicateTx: "OutPoint index has been spent", ErrAPIInsufficient: "Insufficient balance", ErrAPIFailedToMaxwell: "Failed convert the amount", ErrAPIFindingUtxo: "Failed to find Utxo", ErrAPIFindingBalance: "Failed to find balance", ErrAPIWalletInternal: "Error in wallet internal", ErrAPICreateRedeemScript: "Failed to create redeem script", ErrAPICreatePubKey: "Failed to create pubkey", ErrAPICreateAddress: "Failed to create address", ErrAPINoAddressInWallet: "There is no such address in the wallet", ErrAPIInvalidParameter: "Invalid parameter", ErrAPIInvalidLockTime: "Invalid locktime", ErrAPIInvalidAmount: "Invalid amount", ErrAPIInvalidAddress: "Invalid address", ErrAPIInvalidFlag: "Invalid sighash parameter", ErrAPICreatePkScript: "Failed to create pkScript", ErrAPIFailedDecodeAddress: "Failed to decode address", ErrAPIDecodeHexString: "Argument must be hexadecimal string", ErrAPIShaHashFromStr: "Failed to decode hash from string", ErrAPIEncode: "Failed to encode data", ErrAPIDeserialization: "Failed to deserialize", ErrAPIDecodePrivKey: "Failed to decode WIF for the privkey", ErrAPIDisasmScript: "Failed to disasm script to string", ErrAPINet: "Mismatched network", ErrAPINoPrivKeyByPubKey: "No privkey for the pubkey found", ErrAPINoScriptByAddress: "No redeem script for the address found", ErrAPISignTx: "Failed to sign transaction", ErrAPINewEngine: "Failed to create new engine", ErrAPIExecute: "Failed to execute engine", ErrAPIRejectTx: "Reject receive transaction", ErrAPIExtractPKScript: "Failed to extract info from pkScript", ErrAPINewestHash: "Failed to get newest hash", ErrAPIBlockNotFound: "Failed to find block", ErrAPIRawTx: "Failed to create raw transaction", ErrAPINextBlock: "No next block", ErrAPIBlockHashByHeight: "Failed to get block hash by height", ErrAPIBlockHeaderNotFound: "Failed to find block header", ErrNoMinningAddrress: "No payment addresses specified via --miningaddr", ErrAPIUnknownErr: "Unknown error", ErrAPIEstimateTxFee: "Failed to estimateTxFee", ErrAPINoSeedsInWallet: "No seeds", }
var ( // Blockchain ErrTxAlreadyExists = errors.New("transaction already exists") )
Functions ¶
func Detail ¶
Detail returns the detail message contained in err, if any. An error has a detail message if it was made by WithDetail or WithDetailf.
func Root ¶
Root returns the original error that was wrapped by one or more calls to Wrap. If e does not wrap other errors, it will be returned as-is.
func Sub ¶
Sub returns an error containing root as its root and taking all other metadata (stack trace, detail, message, and data items) from err.
Sub returns nil when either root or err is nil.
Use this when you need to substitute a new root error in place of an existing error that may already hold a stack trace or other metadata.
func WithData ¶
WithData returns a new error that wraps err as a chain error message containing a value of type map[string]interface{} as an extra data item. The map contains the values in the map in err, if any, plus the items in keyval. Keyval takes the form
k1, v1, k2, v2, ...
Values kN must be strings. Calling Data on the returned error yields the map. Note that if err already has a data item of any other type, it will not be accessible via the returned error value.
func WithDetail ¶
WithDetail returns a new error that wraps err as a chain error messsage containing text as its additional context. Function Detail will return the given text when called on the new error value.
func WithDetailf ¶
WithDetailf is like WithDetail, except it formats the detail message as in fmt.Printf. Function Detail will return the formatted text when called on the new error value.
Types ¶
type StackFrame ¶
StackFrame represents a single entry in a stack trace.
func Stack ¶
func Stack(err error) []StackFrame
Stack returns the stack trace of an error. The error must contain the stack trace, or wrap an error that has a stack trace,
func (StackFrame) String ¶
func (f StackFrame) String() string
String satisfies the fmt.Stringer interface.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer is in an implementation of the "sticky error writer" pattern as described in https://blog.golang.org/errors-are-values.
A Writer makes one call on the underlying writer for each call to Write, until an error is returned. From that point on, it makes no calls on the underlying writer, and returns the same error value every time.