Categorygithub.com/cpuguy83/strongerrors
modulepackage
0.2.1
Repository: https://github.com/cpuguy83/strongerrors.git
Documentation: pkg.go.dev

# README

strongerrors

A simple Go package for defining common error classes.

Commonly in go applications you either end up defining lots of custom, seminal errors or even custom error types and checking directly against those types. A problem with this pattern is it becomes difficult to wrap errors with extra context without masking the underlying error and potentially causing an error check to miss. The errors package helps to solve some of this where you can use the errors.Wrap pattern to wrap errors and then errors.Cause() to traverse the causal chain. Unfortunately there still exists a problem of requiring deep knowledge and reliance on underlying packages that you may not even control in order to check errors against.

This package defines a common set of error interfaces that can be used in your packages to so that consumers of your package do not need to know about the real error types, or compare even seminal errors. This enables users to worry about the kind of failure rather than its underlying type. These interfaces can be bubbled all the way up the stack to produce proper error codes (or wrapped and converted to another error code) in your RPC of choice (e.g. http or GRPC).

This is mostly taken from github.com/moby/moby/api/errdefs which I helped create to solve some of the above issues in that codebase.

Example Usage

type errNotFound string

func(e errNotFound) Error() string {
	return "not found: " + e
}

func(errNotFound) NotFound() {}

type Foo struct{}

func Get(id string) (*Foo, error) {
	return nil, errNotFound(id)
}

func(w http.ResponseWriter, req *http.Request) {
	id := getID(req)
	f, err := Get(id)
	if err != nil {
		if IsNotFound(err) {
			http.Error(w, err.Error(), http.StatusNotFound)
			return
		}
		http.Error{(w, err.Error(), http.StatusInternalServerError)}
		return
	}
	// yay there's a foo object
}

Alternatively, you can use one of the helper functions instead of defining your own error types:

	func Get(id string) (*Foo, error) {
		return nil, NotFound(errors.New("not found"))
	}

There are also helpers for converting errors to status codes (or GRPC status errors), but you can also implement your own mapping.

	if err != nil {
		code, ok := status.HTTPCode(err)
		if !ok {
			// error type didn't match a defined type
		}
		http.Error(w, err.Error(), code)
		return
	}
	err := status.FromGRPC(err)
	switch {
	case IsNotFound(err):
		// do stuff
	}
	if err != nil {
		return ToGRPC(err)
	}

These errors can be used in conjuction with errors.Wrap from the erros package. To properly check the error type you should use the Is<Kind> helpers which checks the full causal chain.

Contributions

Contributions are always welcome. Keep in mind that the scope of this package is quite small, and the error classes should be kept to a minimum. The thing to keep in mind when thinking about new error classes is "How will the caller be able to react to this error". The existing errors should cover most error cases.

If you think we're missing a case open an issue so we can discuss it.

# Packages

No description provided by the author

# Functions

AlreadyExists is a helper to create an error of the class with the same name from any error type.
Cancelled is a helper to create an error of the class with the same name from any error type.
Conflict is a helper to create an error of the class with the same name from any error type.
DataLoss is a helper to create an error of the class with the same name from any error type.
Deadline is a helper to create an error of the class with the same name from any error type.
Exhausted is a helper to create an error of the class with the same name from any error type.
Forbidden is a helper to create an error of the class with the same name from any error type.
FromContext returns the error class from the passed in context.
InvalidArgument is a helper to create an error of the class with the same name from any error type.
IsAlreadyExists returns if the passed in error is a AlreadyExists error.
IsCancelled returns if the passed in error is an ErrCancelled.
IsConflict returns if the passed in error is an ErrConflict.
IsDataLoss returns if the passed in error is an ErrDataLoss.
IsDeadline returns if the passed in error is an ErrDeadline.
IsExhausted returns if the passed in error is an ErrDeadline.
IsForbidden returns if the passed in error is an ErrForbidden.
IsInvalidArgument returns if the passed in error is an ErrInvalidParameter.
IsNotFound returns if the passed in error is an ErrNotFound.
IsNotImplemented returns if the passed in error is an ErrNotImplemented.
IsNotModified returns if the passed in error is a NotModified error.
IsSystem returns if the passed in error is an ErrSystem.
IsUnauthenticated returns if the the passed in error is an ErrUnauthenticated.
IsUnauthorized returns if the the passed in error is an ErrUnauthorized.
IsUnavailable returns if the passed in error is an ErrUnavailable.
IsUnknown returns if the passed in error is an ErrUnknown.
NotFound is a helper to create an error of the class with the same name from any error type.
NotImplemented is a helper to create an error of the class with the same name from any error type.
NotModified is a helper to create an error of the class with the same name from any error type.
System is a helper to create an error of the class with the same name from any error type.
Unauthenticated is a helper to create an error of the class with the same name from any error type.
Unauthorized is a helper to create an error of the class with the same name from any error type.
Unavailable is a helper to create an error of the class with the same name from any error type.
Unknown is a helper to create an error of the class with the same name from any error type.

# Interfaces

ErrAlreadyExists is a special case of ErrNotModified which signals that the desired object already exists.
ErrCancelled signals that the action was cancelled.
ErrConflict signals that some internal state conflicts with the requested action and can't be performed.
ErrDataLoss indicates that data was lost or there is data corruption.
ErrDeadline signals that the deadline was reached before the action completed.
ErrExhausted indicates that the action cannot be performed because some resource is exhausted.
ErrForbidden signals that the requested action cannot be performed under any circumstances.
ErrInvalidArgument signals that the user input is invalid.
ErrNotFound signals that the requested object doesn't exist.
ErrNotImplemented signals that the requested action/feature is not implemented on the system as configured.
ErrNotModified signals that an action can't be performed because it's already in the desired state.
ErrSystem signals that some internal error occurred.
ErrUnauthenticated is used to indicate that the caller cannot be identified.
ErrUnauthorized is used to signify that the user is not authorized to perform a specific action.
ErrUnavailable signals that the requested action/subsystem is not available.
ErrUnknown signals that the kind of error that occurred is not known.