errorkit

package
v0.164.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 17, 2023 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Finish added in v0.154.0

func Finish(returnErr *error, blk func() error)

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"
	"github.com/adamluzsi/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 HasTag

func HasTag(err error, tags ...any) bool
Example
package main

import (
	"fmt"

	"github.com/adamluzsi/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
}
Output:

func LookupContext

func LookupContext(err error) (context.Context, bool)

func LookupDetail

func LookupDetail(err error) (string, bool)

func Merge

func Merge(errs ...error) error

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"

	"github.com/adamluzsi/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 Tag

func Tag[Tag ~struct{}](err error, tag Tag) error
Example
package main

import (
	"fmt"

	"github.com/adamluzsi/frameless/pkg/errorkit"
)

func main() {
	type MyTag struct{}
	err := fmt.Errorf("foo bar baz")
	err = errorkit.Tag(err, MyTag{})
	errorkit.HasTag(err, MyTag{}) // true
}
Output:

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"

func (Error) Error

func (err Error) Error() string

Error implement the error interface

Example
package main

import (
	"github.com/adamluzsi/frameless/pkg/errorkit"
)

func main() {
	const ErrSomething errorkit.Error = "something is an error"
}
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 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 consttypes.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 consttypes.String
}
Example
package main

import (
	"errors"
	"fmt"
	"math/rand"

	"github.com/adamluzsi/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)
	}
}
Output:

func LookupUserError

func LookupUserError(err error) (UserError, bool)
Example
package main

import (
	"fmt"

	"github.com/adamluzsi/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)
	}
}
Output:

func (UserError) Error

func (err UserError) Error() string

func (UserError) With

func (err UserError) With() WithBuilder
Example
package main

import (
	"github.com/adamluzsi/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)

}
Output:

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"

	"github.com/adamluzsi/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
}
Output:

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"

	"github.com/adamluzsi/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
}
Output:

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"

	"github.com/adamluzsi/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
}
Output:

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL