Documentation
¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ToMap ¶
ToMap converts error into map. If the err implements `Map() map[string]any`, it calls Map(). ToMap returns nil when the err is nil.
Example ¶
package main
import (
"errors"
"fmt"
"github.com/aileron-projects/go-errkit"
)
func main() {
e1 := errors.New("example1")
e2 := errors.New("example2")
fmt.Println(errkit.ToMap(e1))
fmt.Println(errkit.ToMap(fmt.Errorf("example3 [%w]", e1)))
fmt.Println(errkit.ToMap(errors.Join(e1, e2)))
}
Output: map[message:example1] map[causes:[map[message:example1]] message:example3 [example1]] map[causes:[map[message:example1] map[message:example2]] message:example1 example2]
func ToSlogAttr ¶
ToSlogAttr converts error into slog.Attr. ToSlogAttr is the alias for slog.GroupAttrs("error", ToSlogAttrs(err)...)
Example ¶
package main
import (
"errors"
"fmt"
"github.com/aileron-projects/go-errkit"
)
func main() {
e1 := errors.New("example1")
e2 := errors.New("example2")
fmt.Println(errkit.ToSlogAttr(e1))
fmt.Println(errkit.ToSlogAttr(fmt.Errorf("example3 [%w]", e1)))
fmt.Println(errkit.ToSlogAttr(errors.Join(e1, e2)))
}
Output: error=[message=example1] error=[message=example3 [example1] cause=[message=example1]] error=[message=example1 example2 cause.1=[message=example1] cause.2=[message=example2]]
func ToSlogAttrs ¶
ToSlogAttrs converts error into slog.Attr. If the err implements `SlogAttrs() []slog.Attr`, it calls SlogAttrs(). ToSlogAttrs returns nil when the err is nil.
Example ¶
package main
import (
"errors"
"fmt"
"github.com/aileron-projects/go-errkit"
)
func main() {
e1 := errors.New("example1")
e2 := errors.New("example2")
fmt.Println(errkit.ToSlogAttrs(e1))
fmt.Println(errkit.ToSlogAttrs(fmt.Errorf("example3 [%w]", e1)))
fmt.Println(errkit.ToSlogAttrs(errors.Join(e1, e2)))
}
Output: [message=example1] [message=example3 [example1] cause=[message=example1]] [message=example1 example2 cause.1=[message=example1] cause.2=[message=example2]]
func UnwrapErr ¶
UnwrapErr returns the result of calling the Unwrap method on err if the given err implements Unwrap() that returns an error. Otherwise, UnwrapErr returns nil.
UnwrapErr only calls a method of the form "Unwrap() error". In particular UnwrapErr does not unwrap errors returned by errors.Join. See also UnwrapErrs and errors.Unwrap.
func UnwrapErrs ¶
UnwrapErrs returns the result of calling the Unwrap method on err if the given err implements Unwrap() that returns a []error. Otherwise, UnwrapErrs returns nil slice.
UnwrapErrs only calls a method of the form "Unwrap() []error". UnwrapErrs can unwrap errors returned by errors.Join. See also UnwrapErr and errors.Unwrap.
Types ¶
type ErrDefinition ¶
type ErrDefinition struct {
// Code is the error code.
Code string
// Kind is the error kind of this error.
Kind string
// Message is the error message.
// Message will be formatted by [fmt.Sprintf].
Message string
// Attrs is the list of attributions.
// Attrs will be copied to all instances.
Attrs map[string]string
// Instance returns an instance identifier.
Instance func() string
}
ErrDefinition is the error definition. Error instances are created from the definition.
func NewErrDefinition ¶
func NewErrDefinition(code, kind, message string, attrs map[string]string, instance func() string) *ErrDefinition
NewErrDefinition returns a new instance of ErrDefinition. See ErrDefinition.
func (*ErrDefinition) Instanciated ¶
func (d *ErrDefinition) Instanciated(err error) bool
Instanciated returns if this definition instanciated the err. The err will be unwrapped if possible.
func (*ErrDefinition) New ¶
func (d *ErrDefinition) New(cause error, values ...any) *ErrInstance
New returns a new error instance from the definition. Use ErrDefinition.NewStack when stack frames are necessary.
Example ¶
package main
import (
"fmt"
"io"
"github.com/aileron-projects/go-errkit"
)
func main() {
def := errkit.NewErrDefinition("E123", "KindXXX", "example error. foo=%s bar=%s.", map[string]string{"foo": "bar"}, nil)
fmt.Println(def.New(nil, "FOO", "BAR").Error()) // With arguments.
fmt.Println(def.New(nil).Error()) // No arguments.
fmt.Println(def.New(nil, "FOO").Error()) // Insufficient arguments.
fmt.Println(def.New(nil, "FOO", "BAR", "BAZ").Error()) // Too many arguments.
fmt.Println(def.New(io.EOF, "FOO", "BAR").Error()) // With inner error.
}
Output: E123 KindXXX :example error. foo=FOO bar=BAR. (foo=bar) E123 KindXXX :example error. foo=%!s(MISSING) bar=%!s(MISSING). (foo=bar) E123 KindXXX :example error. foo=FOO bar=%!s(MISSING). (foo=bar) E123 KindXXX :example error. foo=FOO bar=BAR.%!(EXTRA string=BAZ) (foo=bar) E123 KindXXX :example error. foo=FOO bar=BAR. (foo=bar) [EOF]
func (*ErrDefinition) NewStack ¶
func (d *ErrDefinition) NewStack(cause error, values ...any) *ErrInstance
NewStack returns a new error instance from the definition. Use ErrDefinition.New when stack frames are not necessary.
type ErrInstance ¶
type ErrInstance struct {
// Cause is the error cause, or inner error.
Cause error `json:"cause,omitempty" msgpack:"cause,omitempty" xml:"cause,omitempty" yaml:"cause,omitempty"`
// Code is the error code, name or alias for the error.
// Code is compared in [Errors.Is].
Code string `json:"code" msgpack:"code" xml:"code" yaml:"code"`
// Kind is the error kind.
// Kind is compared in [Errors.Is].
Kind string `json:"kind" msgpack:"kind" xml:"kind" yaml:"kind"`
// Instance is the instance identifier.
// Instance is NOT compared in [Errors.Is].
Instance string `json:"instance,omitempty" msgpack:"instance,omitempty" xml:"instance,omitempty" yaml:"instance,omitempty"`
// Message is the error message.
Message string `json:"message" msgpack:"message" xml:"message" yaml:"message"`
// Attrs are the attribution, or extra information, to this error.
Attrs map[string]string `json:"attrs" msgpack:"attrs" xml:"attrs" yaml:"attrs"`
// Frames is the list of stack trace frames.
Frames []Frame `json:"frames,omitempty" msgpack:"frames,omitempty" xml:"frames,omitempty" yaml:"frames,omitempty"`
}
Error is the general error type.
func (*ErrInstance) Error ¶
func (e *ErrInstance) Error() string
Error implements [error] interface.
func (*ErrInstance) Is ¶
func (e *ErrInstance) Is(err error) bool
Is returns if this error is identical to the given error. This can be used with errors.Is.
func (*ErrInstance) Map ¶
func (e *ErrInstance) Map() map[string]any
Map returns error information as map.
func (*ErrInstance) SlogAttr ¶
func (e *ErrInstance) SlogAttr() slog.Attr
SlogAttr returns error information as slog.Attr. SlogAttr is the alias for slog.GroupAttrs("error", e.SlogAttrs()...)
Example ¶
package main
import (
"context"
"io"
"log/slog"
"os"
"github.com/aileron-projects/go-errkit"
)
func removeTime(groups []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey && len(groups) == 0 {
return slog.Attr{}
}
return a
}
func main() {
opts := &slog.HandlerOptions{
ReplaceAttr: removeTime,
}
lgJSON := slog.New(slog.NewJSONHandler(os.Stdout, opts))
lgText := slog.New(slog.NewTextHandler(os.Stdout, opts))
def := errkit.NewErrDefinition("E123", "KindXXX", "example. foo=%s", map[string]string{"tag": "val"}, func() string { return "ABC" })
err := def.New(io.EOF, "bar")
lgJSON.InfoContext(context.Background(), "message.", err.SlogAttr())
lgText.InfoContext(context.Background(), "message.", err.SlogAttr())
}
Output: {"level":"INFO","msg":"message.","error":{"code":"E123","kind":"KindXXX","message":"example. foo=bar","attrs":{"tag":"val"},"instance":"ABC","cause":{"message":"EOF"}}} level=INFO msg=message. error.code=E123 error.kind=KindXXX error.message="example. foo=bar" error.attrs.tag=val error.instance=ABC error.cause.message=EOF
func (*ErrInstance) SlogAttrs ¶
func (e *ErrInstance) SlogAttrs() []slog.Attr
SlogAttrs returns error information as slog.Attr.
Example ¶
package main
import (
"context"
"io"
"log/slog"
"os"
"github.com/aileron-projects/go-errkit"
)
func removeTime(groups []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey && len(groups) == 0 {
return slog.Attr{}
}
return a
}
func main() {
opts := &slog.HandlerOptions{
ReplaceAttr: removeTime,
}
lgJSON := slog.New(slog.NewJSONHandler(os.Stdout, opts))
lgText := slog.New(slog.NewTextHandler(os.Stdout, opts))
def := errkit.NewErrDefinition("E123", "KindXXX", "example. foo=%s", map[string]string{"tag": "val"}, func() string { return "ABC" })
err := def.New(io.EOF, "bar")
lgJSON.InfoContext(context.Background(), "message.", "error", err.SlogAttrs())
lgText.InfoContext(context.Background(), "message.", "error", err.SlogAttrs())
}
Output: {"level":"INFO","msg":"message.","error":{"code":"E123","kind":"KindXXX","message":"example. foo=bar","attrs":{"tag":"val"},"instance":"ABC","cause":{"message":"EOF"}}} level=INFO msg=message. error.code=E123 error.kind=KindXXX error.message="example. foo=bar" error.attrs.tag=val error.instance=ABC error.cause.message=EOF
func (*ErrInstance) Unwrap ¶
func (e *ErrInstance) Unwrap() error
Unwrap returns the inner error if any.
type Error ¶
type Error struct {
// Cause is the cause of this error, or inner error.
Cause error
// Message is the error message.
// Message is compared in the [Error.Is].
Message string
// Detail is the error detail.
// Detail is NOT compared in the [Error.Is].
Detail string
}
Error is the basic error struct. Use NewError to create an instance.
func (*Error) Is ¶
Is returns if this error is identical to the given error. This can be used with errors.Is.
func (*Error) SlogAttr ¶
SlogAttr returns error information as slog.Attr. SlogAttr is the alias for slog.GroupAttrs("error", e.SlogAttrs()...)
Example ¶
package main
import (
"context"
"io"
"log/slog"
"os"
"github.com/aileron-projects/go-errkit"
)
func removeTime(groups []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey && len(groups) == 0 {
return slog.Attr{}
}
return a
}
func main() {
opts := &slog.HandlerOptions{
ReplaceAttr: removeTime,
}
lgJSON := slog.New(slog.NewJSONHandler(os.Stdout, opts))
lgText := slog.New(slog.NewTextHandler(os.Stdout, opts))
err := errkit.NewError(io.EOF, "example", "foo=%s", "bar")
lgJSON.InfoContext(context.Background(), "message.", err.SlogAttr())
lgText.InfoContext(context.Background(), "message.", err.SlogAttr())
}
Output: {"level":"INFO","msg":"message.","error":{"message":"example","detail":"foo=bar","cause":{"message":"EOF"}}} level=INFO msg=message. error.message=example error.detail="foo=bar" error.cause.message=EOF
func (*Error) SlogAttrs ¶
SlogAttrs returns error information as slog.Attr.
Example ¶
package main
import (
"context"
"io"
"log/slog"
"os"
"github.com/aileron-projects/go-errkit"
)
func removeTime(groups []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey && len(groups) == 0 {
return slog.Attr{}
}
return a
}
func main() {
opts := &slog.HandlerOptions{
ReplaceAttr: removeTime,
}
lgJSON := slog.New(slog.NewJSONHandler(os.Stdout, opts))
lgText := slog.New(slog.NewTextHandler(os.Stdout, opts))
err := errkit.NewError(io.EOF, "example", "foo=%s", "bar")
lgJSON.InfoContext(context.Background(), "message.", "error", err.SlogAttrs())
lgText.InfoContext(context.Background(), "message.", "error", err.SlogAttrs())
}
Output: {"level":"INFO","msg":"message.","error":{"message":"example","detail":"foo=bar","cause":{"message":"EOF"}}} level=INFO msg=message. error.message=example error.detail="foo=bar" error.cause.message=EOF
type Frame ¶
type Frame struct {
// Pkg is go package name of the caller.
Pkg string `json:"pkg" msgpack:"pkg" toml:"pkg" xml:"pkg" yaml:"pkg"`
// File is the file name of the caller.
File string `json:"file" msgpack:"file" toml:"file" xml:"file" yaml:"file"`
// Func is the function name of the caller.
Func string `json:"func" msgpack:"func" toml:"func" xml:"func" yaml:"func"`
// Line is the line number of the caller.
Line int `json:"line" msgpack:"line" toml:"line" xml:"line" yaml:"line"`
}
Frame holds stack frame location. See also runtime.Frame.