Documentation
¶
Index ¶
- func As[T error](err error) (T, bool)
- func Finish(returnErr *error, blk func() error)
- func FinishOnError(returnErr *error, blk func())
- func HasTag(err error, tags ...any) bool
- func LookupContext(err error) (context.Context, bool)
- func LookupDetail(err error) (string, bool)
- func Merge(errs ...error) error
- func Recover(returnErr *error)
- func RecoverWith(blk func(r any))
- func Tag[Tag ~struct{}](err error, tag Tag) error
- func WithTrace(err error) error
- type Error
- type ErrorHandler
- type StackFrame
- type Traced
- type UserError
- type WithBuilder
- func (w WithBuilder) Context(ctx context.Context) WithBuilder
- func (w WithBuilder) Detail(detail string) WithBuilder
- func (w WithBuilder) Detailf(format string, a ...any) WithBuilder
- func (w WithBuilder) Error() string
- func (w WithBuilder) Unwrap() error
- func (w WithBuilder) Wrap(err error) WithBuilder
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func As ¶ added in v0.201.0
As function serves as a shorthand to enable one-liner error handling with errors.As. It's meant to be used within an if statement, much like Lookup functions such as os.LookupEnv.
Example ¶
package main
import (
"fmt"
"go.llib.dev/frameless/pkg/errorkit"
)
type MyError struct {
Msg string
}
func (err MyError) Error() string {
return err.Msg
}
func main() {
var err error // some error to be checked
if err, ok := errorkit.As[MyError](err); ok {
fmt.Println(err.Msg)
}
}
func Finish ¶
Finish is a helper function that can be used from a deferred context.
Usage:
defer errorkit.Finish(&returnError, rows.Close)
Example (SqlRows) ¶
package main
import (
"database/sql"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
var db *sql.DB
myExampleFunction := func() (rErr error) {
rows, err := db.Query("SELECT FROM mytable")
if err != nil {
return err
}
defer errorkit.Finish(&rErr, rows.Close)
for rows.Next() {
if err := rows.Scan(); err != nil {
return err
}
}
return rows.Err()
}
if err := myExampleFunction(); err != nil {
panic(err.Error())
}
}
func FinishOnError ¶ added in v0.260.0
func FinishOnError(returnErr *error, blk func())
FinishOnError is a helper function that can be used from a deferred context. It runs the block conditionally, when the return error, which was assigned by the `return` keyword is not nil.
Usage:
defer errorkit.FinishOnError(&returnError, func() { rollback(ctx) })
Example ¶
package main
import (
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
// example function
var _ = func() (rerr error) {
defer errorkit.FinishOnError(&rerr, func() { /* do something when the */ })
return errorkit.Error("boom")
}
}
func HasTag ¶
Example ¶
package main
import (
"fmt"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
type MyTag struct{}
err := fmt.Errorf("foo bar baz")
errorkit.HasTag(err, MyTag{}) // false
err = errorkit.Tag(err, MyTag{})
errorkit.HasTag(err, MyTag{}) // true
}
func LookupDetail ¶
func Merge ¶
Merge will combine all given non nil error values into a single error value. If no valid error is given, nil is returned. If only a single non nil error value is given, the error value is returned.
Example ¶
package main
import (
"fmt"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
// creates an error value that combines the input errors.
err := errorkit.Merge(fmt.Errorf("foo"), fmt.Errorf("bar"), nil)
_ = err
}
func Recover ¶ added in v0.184.0
func Recover(returnErr *error)
Recover will attempt a recover, and if recovery yields a value, it sets it as an error.
func RecoverWith ¶ added in v0.272.0
func RecoverWith(blk func(r any))
RecoverWith will attempt a recover, and if recovery yields a non nil value, it executs the passed function.
Example ¶
package main
import (
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
defer errorkit.RecoverWith(func(r any) { /* do something with "r" */ })
/* do something that might panic */
}
func Tag ¶
Example ¶
package main
import (
"fmt"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
type MyTag struct{}
err := fmt.Errorf("foo bar baz")
err = errorkit.Tag(err, MyTag{})
errorkit.HasTag(err, MyTag{}) // true
}
func WithTrace ¶ added in v0.280.0
Example ¶
package main
import (
"errors"
"fmt"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
const ErrBase errorkit.Error = "some error that we get back from a function call"
// traced error that we can return
err := errorkit.WithTrace(ErrBase)
// if we receive back a traced error from a function call, calling WithTrace wonn't reset the trace
err = errorkit.WithTrace(err)
// maybe we have some additional trace wrapping
err = fmt.Errorf("wrapping the erro: %w", err)
var traced errorkit.Traced
_ = errors.As(err, &traced) // true
_ = traced.Trace // stack trace
}
Types ¶
type Error ¶
type Error string
Error is an implementation for the error interface that allow you to declare exported globals with the `consttypes` keyword.
TL;DR: consttypes ErrSomething errorkit.Error = "something is an error"
Example ¶
package main
import (
"errors"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
var (
err1 error = errors.New("first error")
err2 error = errors.New("second error")
err3 error = nil
)
err := errorkit.Merge(err1, err2, err3)
errors.Is(err, err1) // true
errors.Is(err, err2) // true
errors.Is(err, err3) // true
}
func (Error) Error ¶
Error implement the error interface
Example ¶
package main
import (
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
const ErrSomething errorkit.Error = "something is an error"
_ = ErrSomething
}
type ErrorHandler ¶
type ErrorHandler interface {
// HandleError allow the interactor implementation to be notified about unexpected situations.
HandleError(ctx context.Context, err error) error
}
ErrorHandler describes that an object able to handle error use-cases for its purpose.
For e.g. if the component is a pubsub subscription event handler, then implementing ErrorHandler means it suppose to handle unexpected use-cases such as connection interruption.
type StackFrame ¶ added in v0.280.0
func (StackFrame) String ¶ added in v0.280.0
func (f StackFrame) String() string
type Traced ¶ added in v0.280.0
type Traced struct {
Err error
Trace []StackFrame
}
type UserError ¶
type UserError struct {
// ID is a constant string value that expresses the user's error scenario.
// The caller who receives the error will use this code to present the UserError to their users and,
// most likely, provide a localised error message about the error scenario to the end user.
// Traditionally this should be a string without any white space.
//
// Example: "foo-is-forbidden-with-active-baz"
ID constant.String
// Message is the error message meant to be read by a developer working on the implementation of the caller.
// It is not expected to be seen by end users.
// It might be written in English for portability reasons.
//
// Example: "Authentication failed due to incorrect username or password."
Message constant.String
}
Example ¶
package main
import (
"errors"
"fmt"
"math/rand"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
fooEntityID := rand.Int()
bazEntityID := rand.Int()
usrerr := errorkit.UserError{
ID: "foo-is-forbidden-with-active-baz",
Message: "It is forbidden to execute Foo when you have an active Baz",
}
var err error = usrerr.With().Detailf("Foo(ID:%d) /Baz(ID:%d)", fooEntityID, bazEntityID)
// add some details using error wrapping
err = fmt.Errorf("some wrapper layer: %w", err)
// retrieve with errors pkg
if ue := (errorkit.UserError{}); errors.As(err, &ue) {
fmt.Printf("%#v\n", ue)
}
if errors.Is(err, errorkit.UserError{}) {
fmt.Println("it's a Layer 8 error")
}
// retrieve with errorkit pkg
if userError, ok := errorkit.LookupUserError(err); ok {
fmt.Printf("%#v\n", userError)
}
}
func LookupUserError ¶
Example ¶
package main
import (
"fmt"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
err := errorkit.UserError{
ID: "constant-err-scenario-code",
Message: "some message for the dev",
}
if userError, ok := errorkit.LookupUserError(err); ok {
fmt.Printf("%#v\n", userError)
}
}
func (UserError) With ¶
func (err UserError) With() WithBuilder
Example ¶
package main
import (
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
usrErr := errorkit.UserError{
ID: "foo-is-forbidden-with-active-baz",
Message: "It is forbidden to execute Foo when you have an active Baz",
}
// returns with Err that has additional concrete details
_ = usrErr.With().Detailf("Foo(ID:%d) /Baz(ID:%d)", 42, 7)
}
type WithBuilder ¶
type WithBuilder struct{ Err error }
func With ¶
func With(err error) WithBuilder
func (WithBuilder) Context ¶
func (w WithBuilder) Context(ctx context.Context) WithBuilder
Context will combine an error with a context, so the current context can be used at the place of error handling. This can be useful if tracing ID and other helpful values are kept in the context.
Example ¶
package main
import (
"context"
"fmt"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
err := fmt.Errorf("foo bar baz")
ctx := context.Background()
err = errorkit.With(err).
Context(ctx)
_, _ = errorkit.LookupContext(err) // ctx, true
}
func (WithBuilder) Detail ¶
func (w WithBuilder) Detail(detail string) WithBuilder
Detail will return an error that has explanation as detail attached to it.
Example ¶
package main
import (
"fmt"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
err := fmt.Errorf("foo bar baz")
err = errorkit.With(err).
Detail("it was the foo or bar or baz")
_, _ = errorkit.LookupDetail(err) // "it was the foo or bar or baz", true
}
func (WithBuilder) Detailf ¶
func (w WithBuilder) Detailf(format string, a ...any) WithBuilder
Detailf will return an error that has explanation as detail attached to it. Detailf formats according to a fmt format specifier and returns the resulting string.
Example ¶
package main
import (
"fmt"
"go.llib.dev/frameless/pkg/errorkit"
)
func main() {
err := fmt.Errorf("foo bar baz")
err = errorkit.With(err).
Detailf("--> %s <--", "it was the foo or bar or baz")
_, _ = errorkit.LookupDetail(err) // "--> it was the foo or bar or baz <--", true
}
func (WithBuilder) Error ¶
func (w WithBuilder) Error() string
func (WithBuilder) Unwrap ¶
func (w WithBuilder) Unwrap() error
func (WithBuilder) Wrap ¶
func (w WithBuilder) Wrap(err error) WithBuilder