Documentation
¶
Index ¶
- func As[T error](err error) (T, bool)
- func F(format string, a ...any) error
- func Finish(returnErr *error, blk func() error)
- func FinishOnError(returnErr *error, blk func())
- func LookupContext(err error) (context.Context, bool)
- func Merge(errs ...error) error
- func MergeErrFunc(errFuncs ...ErrFunc) func() error
- func NullErrFunc() error
- func Recover(returnErr *error)
- func RecoverWith(blk func(r any))
- func WithContext(err error, ctx context.Context) error
- func WithTrace(err error) error
- type ErrFunc
- type Error
- type ErrorHandler
- type TracedError
- type UserError
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) } }
Output:
func F ¶ added in v0.289.0
F functions similarly to fmt.Errorf but includes tracing capabilities. In the future, it may incorporate additional utilities from errorkit.
Example ¶
package main import ( "fmt" "go.llib.dev/frameless/pkg/errorkit" ) func main() { const ErrBoom errorkit.Error = "boom!" err := errorkit.F("something went wrong: %w", ErrBoom) if traced, ok := errorkit.As[errorkit.TracedError](err); ok { fmt.Println(traced.Error()) } fmt.Println(err.Error()) }
Output:
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()) } }
Output:
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") } }
Output:
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 }
Output:
func MergeErrFunc ¶ added in v0.285.0
func NullErrFunc ¶ added in v0.285.0
func NullErrFunc() error
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 */ }
Output:
func WithContext ¶ added in v0.281.0
WithContext 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 such as additional logging fields 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.WithContext(err, ctx) _, _ = errorkit.LookupContext(err) // ctx, true }
Output:
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.TracedError _ = errors.As(err, &traced) // true _ = traced.Stack // stack trace }
Output:
Types ¶
type ErrFunc ¶ added in v0.285.0
type ErrFunc = func() error
ErrFunc is a function that checks whether a stateful system currently has an error. For example context.Context#Err is an ErrFunc.
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 }
Output:
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 }
Output:
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 TracedError ¶ added in v0.289.0
func (TracedError) As ¶ added in v0.289.0
func (err TracedError) As(target any) bool
func (TracedError) Error ¶ added in v0.289.0
func (err TracedError) Error() string
func (TracedError) Is ¶ added in v0.289.0
func (err TracedError) Is(target error) bool
func (TracedError) Unwrap ¶ added in v0.289.0
func (err TracedError) Unwrap() error
type UserError ¶
type UserError struct { // Code 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" Code constant.String `ext:"id"` // 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{ Code: "foo-is-forbidden-with-active-baz", Message: "It is forbidden to execute Foo when you have an active Baz", } var err error = usrerr.F("Foo(ID:%d) /Baz(ID:%d)", fooEntityID, bazEntityID) // add some details using error wrapping err = fmt.Errorf("some wrapper layer: %w", err) // retrieve with errorkit.As if ue, ok := errorkit.As[errorkit.UserError](err); ok { fmt.Printf("%#v\n", ue) } // 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) } }
Output:
func LookupUserError ¶
Example ¶
package main import ( "fmt" "go.llib.dev/frameless/pkg/errorkit" ) func main() { err := errorkit.UserError{ Code: "constant-err-scenario-code", Message: "some message for the dev", } if userError, ok := errorkit.LookupUserError(err); ok { fmt.Printf("%#v\n", userError) } }
Output: