Documentation ¶
Overview ¶
package erreur implements structured errors that allow you to add context fields to errors, with fast JSON serialization.
Structured errors ¶
Structured logging with frameworks like zap (https://godoc.org/go.uber.org/zap) is fairly common nowadays, but (at least as far as I could tell) errors with contextual information are still mainly produced with something like Errorf:
connErr := fmt.Errorf("error code %d when connecting to address %s", errCode, someAddr)
To get all the context into a structured log line, you now need to either log the error while the context is in scope (and depending on what you're writing this might not be sensible), return the context somehow, or make do with what you have:
zap.NewExample().Error("failed to load data", zap.Error(connErr), zap.String("addr", someAddr)) Output: {"level":"error","msg":"failed to load data","error":"error code 1234 when connecting to address example.com","addr":"example.com"}
At this point you've lost the benefits of structured logging. So why not have errors that can provide their own context? The erreur package provides a zap-specific (although useful outside of zap) way of creating structured errors to go along with your structured logging:
connErr := erreur.New("connection error", zap.Int("code", 1234), zap.String("addr", "example.com")) // [...] elsewhere in your code zap.NewExample().Error("failed to load data", erreur.Field(connErr)) // Output: {"level":"error","msg":"failed to load data","error":{"msg":"connection error","code":1234,"addr":"example.com"}} // or alternatively json := connErr.JSON()
Index ¶
- func Field(err error) zapcore.Field
- func IsStructured(e error) bool
- func New(message string, fields ...zap.Field) error
- func Structure(cause error, fields ...zap.Field) error
- func Wrap(cause error, message string, fields ...zap.Field) error
- type String
- type Structured
- func (s Structured) Cause() error
- func (s Structured) Error() string
- func (s Structured) Fields() []zapcore.Field
- func (s Structured) JSON() string
- func (s Structured) JSONBuffer() *buffer.Buffer
- func (s Structured) MarshalJSON() ([]byte, error)
- func (s Structured) MarshalLogObject(oe zapcore.ObjectEncoder) error
- func (s Structured) Unwrap() error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Field ¶
Field returns a zap field for err under the key "error". If err is nil, returns a no-op field. If err is a structured error or has one in its error chain, returns a zap.Object field, if err is a plain 'ol error, returns zap.Error
func IsStructured ¶
IsStructured returns true if e or any error in its cause chain is a Structured. Shortcut for
_, found := AsStructured(e)
func New ¶
New returns a new structured error with the given message and fields
Example (Zap) ¶
// How to log errors using zap connErr := New("connection error", zap.Int("code", 1234), zap.String("addr", "example.com")) // [...] elsewhere in your code zap.NewExample().Error("failed to load data", Field(connErr))
Output: {"level":"error","msg":"failed to load data","error":{"msg":"connection error","code":1234,"addr":"example.com"}}
func Structure ¶
Structure returns a structured error with the given error as cause and the zap fields added as context. Good for adding context fields to non-structured errors. Returns nil if err is nil
func Wrap ¶
Wrap cause with a new message and add context fields. Returns nil if cause is nil
Example ¶
const fileName = "someFile" someError := String("insufficient permissions") err := Wrap(someError, "writing to file failed", zap.String("fileName", fileName)) zap.NewExample().Error("failed to flush db", Field(err))
Output: {"level":"error","msg":"failed to flush db","error":{"msg":"writing to file failed","fileName":"someFile"}}
Example (Cause) ¶
const fileName = "someFile" someError := String("insufficient permissions") err := Wrap(someError, "writing to file failed", zap.String("fileName", fileName)) finalErr := Wrap(err, "failed to flush db", zap.String("fieldThatGoes", "ping")) zap.NewExample().Error("failed to flush db", Field(finalErr))
Output: {"level":"error","msg":"failed to flush db","error":{"msg":"failed to flush db","fieldThatGoes":"ping","cause":{"msg":"writing to file failed","fileName":"someFile"}}}
Types ¶
type String ¶
type String string
String is a lightweight string-based error. It has no "constructor", so type conversion should be used instead:
const err = erreur.String("some error text")
type Structured ¶
type Structured struct {
// contains filtered or unexported fields
}
Structured holds an error (and a possible cause for it) and zap Fields that provide context for that error.
func AsStructured ¶
func AsStructured(e error) (err Structured, ok bool)
AsStructured is a shortcut for extracting a structured error from e's error chain. If ok is false, no matching error was found.
func (Structured) Cause ¶
func (s Structured) Cause() error
Cause is the same as Unwrap, but implements the interface in https://github.com/pkg/errors
func (Structured) Error ¶
func (s Structured) Error() string
Error returns just the message of s, with no context fields
func (Structured) Fields ¶
func (s Structured) Fields() []zapcore.Field
Fields returns the fields of s and its causes (recursively)
func (Structured) JSON ¶
func (s Structured) JSON() string
JSON turns s into a JSON string. Shortcut for MarshalJSON that ignores the returned error (uses zap's JSON encoder under the hood which never returns errors, so this is safe™)
func (Structured) JSONBuffer ¶
func (s Structured) JSONBuffer() *buffer.Buffer
JSONBuffer returns a go.uber.org/zap/buffer with the JSON serialization of s
func (Structured) MarshalJSON ¶
func (s Structured) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler
func (Structured) MarshalLogObject ¶
func (s Structured) MarshalLogObject(oe zapcore.ObjectEncoder) error
MarshalLogObject implements zapcore.ObjectMarshaler. This means that you can do the following:
zap.Object("error", s)
See Field for a convenience function
func (Structured) Unwrap ¶
func (s Structured) Unwrap() error
Unwrap returns the cause of this error, or nil if there is none. Implements the new experimental Unwrap interface in https://golang.org/x/exp/errors