Documentation
¶
Overview ¶
Package errors provides a generic error carrying useful information:
- StackTrace for debugging
- 2 different messages: one for the end user and one for the developer
- a Kind: a string that can act as an ID for errors
- a httpStatus
- a timestamp of when the error was created
This error implement the json.Marshaler and xml.Marshaler interface, so you can return this error in your http handlers.
It also implements the errors.Unwrap interface, allowing you to get the previous error.
It depends on the gapi/log package, as the error will implement several of its interfaces to log the errors correctly.
## Create a new error
To create a new error, simply call the Err() function and use the setter to set any data you want.
The setter functions will modify the data and won't create a new error, you don't need to reassign the error.
import ( "net/http" "github.com/mwm-io/gapi/errors" ) err := errors.Err("my error). WithKind("not_found"). WithStatusCode(http.StatusNotFound). WithMessage("not found")
## Wrap an existing error
To wrap an existing error, simply call the Wrap() function. You can then modify the new error as you want.
Wrapping a nil error will return a nil value.
import ( "fmt" "github.com/mwm-io/gapi/errors" ) err := fmt.Errorf("source error") newErr := errors.Wrap(err, "error").WithKind("new_kind")
### Populate data from the source error
You might want to carry more than just the message type from the source error.
In order to do that you need to implement the ErrorBuilder interface and register your builder with an init function.
Your builder should concern a single type of error.
You can read an example with the errors/google package.
import ( "github.com/mwm-io/gapi/errors" ) func init() { errors.AddBuilder() } var GrpcCodeErrorBuilder = errors.ErrorBuilderFunc(func(err errors.Error, sourceError error) errors.Error { sourceErrI, ok := sourceErr.(interface{ WithKind() string }) if !ok { return err } return err.WithKind(sourceErrI.WithKind()) })
## Why is it an interface ?
You may wonder why we use an Error interface and why don't we use the FullError struct directly.
This is because `(*FullError)(nil) != nil`: a nil value with a concrete type won't match nil.
In order to keep the idiomatic `if Err("my err") != nil`, we always return the Error interface.
Index ¶
- func AddBuilders(errorBuilders ...ErrorBuilder)
- type Error
- type ErrorBuilder
- type ErrorBuilderFunc
- type FullError
- func (e *FullError) Error() string
- func (e *FullError) Kind() string
- func (e *FullError) MarshalJSON() ([]byte, error)
- func (e *FullError) MarshalXML(encoder *xml.Encoder, start xml.StartElement) error
- func (e *FullError) Message() string
- func (e *FullError) Severity() gLog.Severity
- func (e *FullError) StackTrace() gLog.StackTrace
- func (e *FullError) StatusCode() int
- func (e *FullError) Timestamp() time.Time
- func (e *FullError) Unwrap() error
- func (e *FullError) WithKind(kind string) Error
- func (e *FullError) WithMessage(message string) Error
- func (e *FullError) WithMessagef(message string, opts ...interface{}) Error
- func (e *FullError) WithSeverity(severity gLog.Severity) Error
- func (e *FullError) WithStackTrace(trace gLog.StackTrace) Error
- func (e *FullError) WithStatus(status int) Error
- func (e *FullError) WithTimestamp(t time.Time) Error
- type HttpError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddBuilders ¶
func AddBuilders(errorBuilders ...ErrorBuilder)
AddBuilders will register the given ErrorBuilder to be used.
Types ¶
type Error ¶
type Error interface { error Unwrap() error json.Marshaler xml.Marshaler Message() string Kind() string StatusCode() int Severity() gLog.Severity Timestamp() time.Time StackTrace() gLog.StackTrace WithMessage(string) Error WithMessagef(string, ...interface{}) Error WithKind(string) Error WithStatus(int) Error WithSeverity(gLog.Severity) Error WithTimestamp(time.Time) Error WithStackTrace(trace gLog.StackTrace) Error }
Error represents the interface for the FullError struct. It is necessary so we can compare nil errors. (nil.(*FullError) != nil)
func Build ¶
Build will call all registered builders to add additional information on the given Error, depending on the sourceError
func Err ¶
Err creates a new Error.
Example ¶
err := Err("this is my error"). WithMessage("message for the final user"). WithKind("error"). WithStatus(http.StatusBadGateway). WithSeverity(gLog.CriticalSeverity). WithStackTrace(stacktrace.New()). WithTimestamp(time.Now()) js, _ := err.MarshalJSON() fmt.Println(string(js))
Output: {"message":"message for the final user","kind":"error"}
func Wrap ¶
Wrap will wrap the given error and return a new Error.
Example ¶
sourceErr := fmt.Errorf("original error") err := Wrap(sourceErr, "wrapped error") fmt.Println(err.Error()) js, _ := err.MarshalJSON() fmt.Println(string(js)) wrappedErr := errors.Unwrap(err) fmt.Println(wrappedErr.Error()) var nilErr error wrappedNilErr := Wrap(nilErr, "nil error") fmt.Printf("%t\n", wrappedNilErr == nil)
Output: wrapped error: original error {"message":"wrapped error","kind":""} original error true
type ErrorBuilder ¶
ErrorBuilder will try to interpret the sourceErr to populate Error with additional data.
type ErrorBuilderFunc ¶
ErrorBuilderFunc is a function that implements the ErrorBuilder interface.
type FullError ¶
type FullError struct {
// contains filtered or unexported fields
}
FullError is a concrete error that implements the Error interface
func (*FullError) Error ¶
FullError implements the error interface. It will return the "developer" message in opposition to the user message, which is returned by FullError.Message
func (*FullError) MarshalJSON ¶
MarshalJSON implements the json.Marshaler interface.
func (*FullError) MarshalXML ¶
MarshalXML implements the xml.Marshaler interface.
func (*FullError) StackTrace ¶
func (e *FullError) StackTrace() gLog.StackTrace
StackTrace returns the error stacktrace.
func (*FullError) StatusCode ¶
StatusCode implements server.WithStatusCode
func (*FullError) WithMessage ¶
WithMessage sets the user message.
func (*FullError) WithMessagef ¶ added in v0.0.5
WithMessagef sets the user message with format.
func (*FullError) WithSeverity ¶
WithSeverity sets the error severity.
func (*FullError) WithStackTrace ¶
func (e *FullError) WithStackTrace(trace gLog.StackTrace) Error
WithStackTrace sets the error stacktrace.
func (*FullError) WithStatus ¶
WithStatus sets the error status. It will also modify the severity for status >= 400