lathos

package module
v0.0.12 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2024 License: MIT Imports: 1 Imported by: 4

README

lathos Go Reference example workflow Go Report Card GitHub go.mod Go version

Greek for error, lathos is an errors package for go.

It utilises checking errors for behaviour, not type or substring. This helps to make error checking elegant and removes dependency on your code from concrete error types.

This library was heavily influenced by a blog from Dave Cheney (Don’t just check errors, handle them gracefully) and is my take on the paradigms discussed there.

Examples

A quick example error check:

err := Do()
if lathos.IsNotFound(err){
	// do something else
}

This is much neater than Sentinel error checking such as:

err := Do()
if strings.Contains(err.Error(), "not found"){
	// do something else
}

This is brittle code, the error could change its message, it could change the casing, meaning you also need to add a strings.ToLower wrapper to handle that and you have to remember the exact text throughout your code to check for specific errors; we all make spelling mistakes...

Lathos is also neater than type checks, type checks are ok, but they tie you to a concrete error implementation:

err := Do()
if ok := err.(lathos.NotFound); ok {
	// do something else
}

This reads ok (in my opinion not as nice as a lathos check though), but if you want to change the NotFound type, you need to update this throughout your code base where you check the errors. You may want to implement your own version of the NotFound error for example.

Usage

Lathos is mostly made up of interfaces that when implemented on an error type give it a particular behaviour, these can be found in the lathos.go file.

There are two main error types:

  1. client - errors to be returned to a client, these would generally be equivalent to 4XX http errors.
  2. internal - server related errors where you will want to record a stack trace, metadata and send it to a logging system

Errors can then derive from these, for example, you could create a NotFound error that embeds a client error, therefor it is both a client error and a notfound error - this will be useful in an error handler where you may want to branch between client and internal errors.

Error Types

The library also has implementations of each error behaviour for your convenience, you can use these in your code base or implement your own error types.

As long as your errors implement the relevant interface, and you use the lathos.Is{ErrorType} methods to check any error implementing the interface will return true in the checks.

Error Handlers

The idea with the library is that it will be used in a service of some kind, you will usually just return errors and let them bubble up.

Occasionally you will expect a particular error such as a Duplicate. At this point, return a Duplicate error.

If you then create a global error handler, you can check the errors in one place, convert to a response of your choosing and return. Or you may log them.

There are some examples in the examples folder.

Compatibility

As this uses features introduced in Go1.13 relating to errors and error checks it will only work in projects using Go 1.13 and above.

It can still be used with the excellent pkg/errors package as from version 0.9.0 they added support for the Go1.13 error types.

Contributions

If you have any suggestions or improvements feel free to add an Issue or create a PR and I'll be very grateful!

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsBadRequest

func IsBadRequest(err error) bool

IsBadRequest will check that an error is a BadRequest type.

func IsCannotProcess

func IsCannotProcess(err error) bool

IsCannotProcess will check that an error is a CannotProcess type.

func IsClientError

func IsClientError(err error) bool

IsClientError is return true if the provided error was of the clientError type.

func IsConflict added in v0.0.12

func IsConflict(err error) bool

IsConflict will check if this is a conflict error.

func IsDuplicate

func IsDuplicate(err error) bool

IsDuplicate can be used throughout your code or in an error handler to check that an err is a Duplicate error. If so, true is returned.

func IsInternalError

func IsInternalError(err error) bool

IsInternalError will return true if this is an InternalError.

func IsNotAuthenticated

func IsNotAuthenticated(err error) bool

IsNotAuthenticated will check that an error is a NotAuthenticated type.

func IsNotAuthorised

func IsNotAuthorised(err error) bool

IsNotAuthorised will check that and error or it's cause was of the NotAuthorised type.

func IsNotFound

func IsNotFound(err error) bool

IsNotFound can be used throughout your code or in an error handler to check that an err is a NotFound error. If so, true is returned.

func IsRetryable added in v0.0.7

func IsRetryable(err error) bool

IsRetryable will check that an error is a Retryable type.

func IsTooManyRequests added in v0.0.11

func IsTooManyRequests(err error) bool

IsTooManyRequests will check if this is a tooManyRequests error.

func IsUnavailable

func IsUnavailable(err error) bool

IsUnavailable will check that an error is an Unavailable type.

Types

type BadRequest

type BadRequest interface {
	BadRequest() bool
}

BadRequest when implemented will indicate that the error is a BadRequest error to be returned when user input is invalid.

type CannotProcess

type CannotProcess interface {
	CannotProcess() bool
}

CannotProcess when implemented will indicate that the request can no longer be processed.

type ClientError

type ClientError interface {
	// ID can contain a correlationID/requestID etc.
	ID() string
	// Code can contain an error code relating to the type of error.
	Code() string
	// Title should not change between errors ie all NotFound errors should have the same title.
	Title() string
	// Detail will return human readable detail.
	Detail() string
	error
}

ClientError defines an error that could be returned to a caller. It should not expose debug or program information but rather useful information for a consuming client. This can be called to build a message type of your choosing to match the transport being used by the server such as http, grpc etc.

type Conflict added in v0.0.12

type Conflict interface {
	Conflict() bool
}

Conflict when implemented will indicate that the request cannot be completed due to a conflict with the current state of the resource.

type Duplicate

type Duplicate interface {
	Duplicate() bool
}

Duplicate when implemented will indicate that the error is a Duplicate error.

type InternalError

type InternalError interface {
	// ID is a unique id for this particular message to help identification
	ID() string
	// Code is an optional error code, all erorrs of the same reason could have
	// a code assigned for machine handling of errors.
	Code() string

	// Message is the human readable reason for the error.
	Message() string
	// Stack is the full stack trace of the error, you may want to redact this in production environments.
	Stack() string
	// Metadata can be used to provide structured fields to an error message.
	Metadata() map[string]interface{}
}

InternalError can be implemented to create errors used to capture internal faults. These could then be sent to an error logging system to be rectified. In terms of a web server, this would be a 5XX error.

type NotAuthenticated

type NotAuthenticated interface {
	NotAuthenticated() bool
}

NotAuthenticated when implemented will indicate that the error is a NotAuthenticated error.

type NotAuthorised

type NotAuthorised interface {
	NotAuthorised() bool
}

NotAuthorised when implemented will indicate that the error is a NotAuthorised error.

type NotFound

type NotFound interface {
	NotFound() bool
}

NotFound when implemented will indicate that the error is a NotFound error.

type Retryable added in v0.0.7

type Retryable interface {
	Retryable() bool
}

Retryable when implemented will indicate that the error is retryable at which point you can try to re-submit as there is a chance it could succeed.

type TooManyRequests added in v0.0.11

type TooManyRequests interface {
	TooManyRequests() bool
}

TooManyRequests when implemented will indicate that too many requests have occurred and the system cannot handle any further requests.

type Unavailable

type Unavailable interface {
	Unavailable() bool
}

Unavailable when implemented will indicate that the service is not currently available. This could also be returned if a database or critical dependency isn't reachable.

Directories

Path Synopsis
Package errs contains optional error types that implement all error behaviours defined in lathos.
Package errs contains optional error types that implement all error behaviours defined in lathos.

Jump to

Keyboard shortcuts

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