apperror

package
v0.0.0-...-6d78eec Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2024 License: MIT Imports: 3 Imported by: 1

Documentation

Overview

Package apperror provides a way to create and match errors with semantics.

Example (Checking_multiple_error_kinds_with_if_and_switch)
package main

import (
	"artk.dev/apperror"
	"fmt"
)

func main() {
	operation := func() error {
		return nil
	}

	// Nesting the switch inside a branch to separate happy and sad paths
	// could be of use sometimes.
	if err := operation(); err != nil {
		// Handle the sad path.
		switch apperror.KindOf(err) {
		case apperror.NotFoundError:
			fmt.Println("Not found:", err)
		case apperror.ConflictError:
			fmt.Println("Conflict:", err)
		case apperror.ForbiddenError:
			fmt.Println("Forbidden:", err)
		default:
			fmt.Println("Other error:", err)
		}
		return
	}

	// Handle the happy path.
	fmt.Println("OK.")

}
Output:

OK.
Example (Checking_multiple_error_kinds_with_switch_only)
package main

import (
	"artk.dev/apperror"
	"fmt"
)

func main() {
	operation := func() error {
		return nil
	}

	switch err := operation(); apperror.KindOf(err) {
	case apperror.OK:
		// You can either handle the error here or leave it blank
		// and handle the normal path without indentation. In either
		// case, you likely want to have a case for OK so that it is
		// not handled by the default clause.
	case apperror.NotFoundError:
		fmt.Println("Not found:", err)
		return
	case apperror.ConflictError:
		fmt.Println("Conflict:", err)
		return
	case apperror.ForbiddenError:
		fmt.Println("Forbidden:", err)
		return
	default:
		fmt.Println("Other error:", err)
		return
	}

	// Handle the happy path.
	fmt.Println("OK.")

}
Output:

OK.
Example (Ignoring_an_already_deleted_item)
package main

import (
	"artk.dev/apperror"
	"fmt"
)

func main() {
	deleteItem := func(x int) error {
		if x == 2 {
			return apperror.NotFound("not found: %v", x)
		}

		return nil
	}

	// In this example, it is acceptable if the items are not found.
	for _, x := range []int{0, 2, 7, 42} {
		err := deleteItem(x)
		if apperror.IsNotFound(err) {
			fmt.Println("Already gone:", x)
			continue
		} else if err != nil {
			fmt.Println("Error:", err)
			return
		}

		fmt.Println("Deleted:", x)
	}

	fmt.Println("Done.")

}
Output:

Deleted: 0
Already gone: 2
Deleted: 7
Deleted: 42
Done.
Example (Retrying_temporary_failures)
package main

import (
	"artk.dev/apperror"
	"fmt"
	"time"
)

func main() {
	// An example operation that can fail temporarily.
	var i int
	operation := func() (int, error) {
		i++
		if i < 3 {
			return i, apperror.Timeout("timed out (%v)", i)
		}

		return i, nil
	}

	// Retry after a temporary failure up to a limited number of times.
	var value int
	var err error
	for range 3 {
		value, err = operation()

		// We went with IsFinal instead of IsTransient or IsTemporary
		// because most of the time you want to break out of a loop.
		// Since IsFinal returns true in that case, we avoid the NOT
		// operator and keep the logic positive. It is also shorter.
		if apperror.IsFinal(err) {
			break
		}

		fmt.Println("Operation failed:", err)
		time.Sleep(time.Nanosecond)
	}
	if err != nil {
		fmt.Println("Unexpected error:", err)
		return
	}

	fmt.Println("Success:", value)
	fmt.Println("Done.")

}
Output:

Operation failed: timed out (1)
Operation failed: timed out (2)
Success: 3
Done.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func As

func As(kind Kind, err error) error

As wraps an existing error into a Kind. Invalid Kind values are mapped to Unknown. If the kind is OK or the error is nil, the function will return nil.

func AsConflict

func AsConflict(err error) error

AsConflict wraps an existing error as a conflict error. It returns nil for nil errors.

func AsForbidden

func AsForbidden(err error) error

AsForbidden wraps an existing error as a forbidden error. It returns nil for nil errors.

func AsNotFound

func AsNotFound(err error) error

AsNotFound wraps an existing error as a not found error. It returns nil for nil errors.

func AsPreconditionFailed

func AsPreconditionFailed(err error) error

AsPreconditionFailed wraps an existing error as a precondition failed error. It returns nil for nil errors.

func AsTimeout

func AsTimeout(err error) error

AsTimeout wraps an existing error as a timeout error. It returns nil for nil errors.

func AsTooManyRequests

func AsTooManyRequests(err error) error

AsTooManyRequests wraps an existing error as a too many requests error. It returns nil for nil errors.

func AsUnauthorized

func AsUnauthorized(err error) error

AsUnauthorized wraps an existing error as a unauthorized error. It returns nil for nil errors.

func AsUnknown

func AsUnknown(err error) error

AsUnknown wraps an existing error as a unknown error. It returns nil for nil errors.

func AsValidation

func AsValidation(err error) error

AsValidation wraps an existing error as a validation error. It returns nil for nil errors.

func Conflict

func Conflict(msg string, a ...any) error

Conflict creates a new conflict error.

func Forbidden

func Forbidden(msg string, a ...any) error

Forbidden creates a new forbidden error.

func IsConflict

func IsConflict(err error) bool

IsConflict matches conflict errors.

func IsFinal

func IsFinal(err error) bool

IsFinal returns true for error kinds that are not expected to change by merely repeating the operation.

Note that this function exclusively considers error kinds, not the context in which they were produced. Not all operations can be repeated safely, and this function cannot provide guidance on making such a judgment.

func IsForbidden

func IsForbidden(err error) bool

IsForbidden matches forbidden errors.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound matches not found errors.

func IsPreconditionFailed

func IsPreconditionFailed(err error) bool

IsPreconditionFailed matches precondition failed errors.

func IsTimeout

func IsTimeout(err error) bool

IsTimeout matches timeout errors.

func IsTooManyRequests

func IsTooManyRequests(err error) bool

IsTooManyRequests matches too many requests errors.

func IsUnauthorized

func IsUnauthorized(err error) bool

IsUnauthorized matches unauthorized errors.

func IsUnknown

func IsUnknown(err error) bool

IsUnknown matches unknown errors.

func IsUser

func IsUser(err error) bool

IsUser returns true for errors that are usually attributable to the user, as opposed to the implementation. For an analogy, think HTTP 400s (client errors) vs. HTTP 500s (server errors).

func IsValidation

func IsValidation(err error) bool

IsValidation matches validation errors.

func New

func New(kind Kind, msg string, a ...any) error

New creates an error of the specified Kind. Invalid Kind values are mapped to Unknown. If the kind is OK, the function will return nil.

func NotFound

func NotFound(msg string, a ...any) error

NotFound creates a new not found error.

func PreconditionFailed

func PreconditionFailed(msg string, a ...any) error

PreconditionFailed creates a new precondition failed error.

func Timeout

func Timeout(msg string, a ...any) error

Timeout creates a new timeout error.

func TooManyRequests

func TooManyRequests(msg string, a ...any) error

TooManyRequests creates a new too many requests error.

func Unauthorized

func Unauthorized(msg string, a ...any) error

Unauthorized creates a new unauthorized error.

func Unknown

func Unknown(msg string, a ...any) error

Unknown returns a semantic error of UnknownError.

While any non-semantic error will be detected as an unknown error, the error returned by this constructor implements the kinder interface and can be checked faster.

func Validation

func Validation(msg string, a ...any) error

Validation creates a new validation error.

Types

type Kind

type Kind int

Kind implies semantic connotations about an error. In most cases, knowing the kind of error is all that user code needs for correct handling, and there is no need to consider the exact error type or message.

The numerical values of these constants are not guaranteed to be stable and therefore must not be relied on.

const (
	OK Kind = iota
	UnknownError
	ValidationError
	UnauthorizedError
	ForbiddenError
	NotFoundError
	ConflictError
	PreconditionFailedError
	TooManyRequestsError
	TimeoutError
)

func KindOf

func KindOf(err error) Kind

KindOf returns the Kind of an error. If the error is nil, it will return OK.

This is usually faster than calling multiple error kind matchers.

func KindValues

func KindValues() []Kind

KindValues returns the set of known values of Kind.

func (Kind) String

func (i Kind) String() string

Jump to

Keyboard shortcuts

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