Documentation ¶
Overview ¶
Package errstack provides a way to augment errors with a functional type and iteratively build new request error.
In software we have 3 types of errors:
* Infrastructure - this errors come from the requests to other services.
* Domain - this is the type of errors when we detect that our internal application state is wrong.
* Request - a user request error.
Request errors maps parameters (or input data fields) to the explanation (why the value of wrong).
Domain errors usually arise form some model bug or unhandled condition.
Infrastructure errors arise from the system or connection error.
It is very handy to know the place (stack) where the error Infrastructure or Domain error arose - that's why they are threatened especially and are augmented with the stack trace.
Index ¶
- func CallAndAssign(err *error, f func() error)
- func CallAndLog(l Logger, f func() error)
- func IsKind(kind Kind, err error) bool
- func IsTimeout(e error) bool
- func Join(es ...error) error
- func Log(l Logger, err error)
- func RootErr(err error) error
- func Seq(ss ...string) error
- type Builder
- type E
- func New(kind Kind, msg string) E
- func NewDomain(s string) E
- func NewDomainF(format string, a ...interface{}) E
- func NewIO(s string) E
- func NewIOf(f string, a ...interface{}) E
- func NewReq(s string) E
- func NewReqDetails(key string, details interface{}, msg string) E
- func NewReqF(f string, a ...interface{}) E
- func Wrap(err error, kind Kind, msg string) E
- func WrapAsDomain(err error, message string) E
- func WrapAsDomainF(err error, f string, a ...interface{}) E
- func WrapAsIO(e error, messages ...string) E
- func WrapAsIOf(err error, f string, a ...interface{}) E
- func WrapAsReq(err error, message string) E
- func WrapAsReqF(err error, f string, a ...interface{}) E
- type HasStacktrace
- type HasStatusCode
- type HasUnderlying
- type Kind
- type ListNode
- type Logger
- type Putter
- type StubPutter
- type UntilFirst
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CallAndAssign ¶
CallAndAssign assigns error returned from the function to the err pointer if needed. Usually useful in defer statements, eg:
CallAndAssign(&err, someFile.Close)
func CallAndLog ¶
CallAndLog calls function which may return error and logs it. The intention of this function is to be used with `go` and `defer` clauses.
func IsKind ¶
IsKind reports whether err is an *Error of the given Kind. If err is nil then Is returns false.
func Join ¶
Join creates a new error from list of errors. It filters out nil errors. If there is no not-nil error it returs nil.
func RootErr ¶
RootErr returns the underlying cause of the error, if possible. Normally it should be the root error. This method uses `HasUnderlying` interface to extract the cause error.
If the error does not implement the `HasUnderlying`, the original error will be returned. If the error is nil, nil will be returned without further investigation.
Types ¶
type Builder ¶
type Builder interface { // Fork creates a new builder which shares the same space but all new added errors // will be assigned to keys prefixed with `prefix` Fork(prefix string) Builder // ForkIdx is a handy function to call Fork with an `int` (eg: index keys / rows) ForkIdx(idx int) Builder // Putter returns a Putter which abstract error setting from error key. Putter(key string) Putter // Puts new error under the key. You can put multiple errors under the same key // and they will be agregated Put(key string, value interface{}) // Get returns errors under `key`. Get is aware about 'prefix' and it will add it // to the the key. Get(key string) interface{} // NotNil checks if there are any errors in the builder. NotNil() bool // Converts the Builder into a request error. ToReqErr() E // ToList transforms Builder errors into a list ToList() []ListNode }
Builder is a type to incrementally build set of errors under common key structure Builder intentionally doesn't implement standard Error interface. You have to explicitly convert it into an Error (using ToReqErr) once all checks are done. Basic idea of builder is to easily combine request errors. Example:
var errb = NewBuilder() if len(obj.Name) < 3 { errb.Put("first_name", "name is too short") } if strings.Contains(obj.Name, "%") { errb.Put("first_name", "name contains invalid characters") } ... return errb.ToReqErr()
func NewBuilder ¶
func NewBuilder() Builder
NewBuilder creates new builders with given prefix being appended to each error keys. This structure is not thread safe.
type E ¶
type E interface { error HasStatusCode HasStacktrace json.Marshaler IsReq() bool Kind() Kind WithMsg(string) E Details() map[string]interface{} Add(key string, payload interface{}) // add more details to the error }
E is error with more information. It is able to marshall itself to json as response. Result of Error() method should include stacktrace. Therefore it should not be displayed directly to the user
func NewDomain ¶
NewDomain creates new domain error from string Domain error is classified as an Infrastructure error.
func NewDomainF ¶
NewDomainF creates new domain error using string formatter
func NewReqDetails ¶
NewReqDetails creates a request error. Key inform which request parameter was invalid and details contains reason of error
func WrapAsDomain ¶
WrapAsDomain creates new domain error using error and string message Domain error is classified as an Infrastructure error.
func WrapAsDomainF ¶
WrapAsDomainF creates new domain error wrapping given error and using string formatter for description. Domain error is classified as an Infrastructure error.
func WrapAsIO ¶
WrapAsIO creates new infrastructure error from simple error If input argument is nil, nil is returned.
func WrapAsIOf ¶
WrapAsIOf creates new infrastructural error wrapping given error and using string formatter for description.
func WrapAsReq ¶
WrapAsReq creates new request error from simple error If input argument is nil, nil is returned. If input argument is already errstack.E, it is returned unchanged.
func WrapAsReqF ¶
WrapAsReqF creates new request error from simple error and creates message from format If input argument is nil, nil is returned. If input argument is already errstack.E, it is returned unchanged.
type HasStacktrace ¶
HasStacktrace provides a function to return the the root stacktrace
type HasStatusCode ¶
type HasStatusCode interface {
StatusCode() int
}
HasStatusCode provides a function to return the HTTP status code.
type HasUnderlying ¶
type HasUnderlying interface { // Cause returns the underlying error (if any) causing the failure. Cause() error }
HasUnderlying describes entity (usually an error) which has underlying error.
type Kind ¶
type Kind uint8
Kind defines the kind of error that must act differently depending on the error
const ( Other Kind = iota // Unclassified error. Invalid // Invalid operation for this type of item. Permission // Permission denied. IO // I/O error such as network failure. Exist // Item already exists. NotExist // Item does not exist. IsDir // Item is a directory. NotDir // Item is not a directory. NotEmpty // Directory not empty. Private // Information withheld. CannotDecrypt // No wrapped key for user with read access. Transient // A transient error. BrokenLink // Link target does not exist. Request // General request error Domain // Internal error causing business domain problem or inconsistency )
Kinds of errors.
type ListNode ¶
type ListNode struct {
// contains filtered or unexported fields
}
ListNode is a representation used by Builder.ToList interface function
type Logger ¶
type Logger interface {
Error(msg string, ctx ...interface{})
}
Logger defines the reporting interface for utils error functions
type Putter ¶
Putter is an interface which provides a way to set an error abstracting from it's identifier (key). Please refer to the Builder documentation to see the example below without using Putter. Example:
validateName(obj.FirstName, errb.Putter("first_name")) validateName(obj.LastName, errb.Putter("last_name")) func validateName(name string, errp.Putter) { if len(name) < 3 { errp.Put(name is too short") } if strings.Contains(name, "%") { errp.Put(name contains invalid characters") } }
type StubPutter ¶
type StubPutter struct {
// contains filtered or unexported fields
}
StubPutter ignores all input. It only contains information whether any input was submitted
func (*StubPutter) HasError ¶
func (rp *StubPutter) HasError() bool
HasError checks if any error occurred
type UntilFirst ¶
type UntilFirst struct {
Err E
}
UntilFirst is a struct to easily chain a sequence of operations until a first error arise
func UntilFirstDo ¶
func UntilFirstDo(f func() E) *UntilFirst
UntilFirstDo is utility method for using UntilFirst