ddderr

package module
v3.3.0 Latest Latest
Warning

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

Go to latest
Published: Mar 8, 2022 License: MIT Imports: 4 Imported by: 0

README

👺 DDD Error

Go Build GoDoc Go Report Card codebeat badge Coverage Status Go Version

DDD Error is a reflection-free Domain-Driven error wrapper made for Go.

Using existing validators such as playground's implementation is overwhelming because tag validation and the need to rewrite descriptions. With DDD Error, you may still use 3rd-party validators or make your own validations in your value objects, entities or aggregates.

In addition, infrastructure exceptions were added so you may be able to catch specific kind of infrastructure errors.

Exceptions descriptions are based on the Google Cloud API Design Guidelines.

DDD Error is compatible with popular error-handling packages such as Hashicorp's go-multierror

In conclusion, DDD Error aims to ease the lack of exception handling in The Go Programming Language by defining a wide selection of common exceptions which happen inside the domain and/or infrastructure layer(s).

Note: DDD Error is dependency-free, it complies with Go's built-in error interface and avoids reflection to increase overall performance.

Installation

Install DDD Error by running the command

go get github.com/neutrinocorp/ddderr/v3

Full documentation is available here

Common Use Cases

  • Implement retry strategy and circuit breaker resiliency patterns by adding Network exception to the whitelist.
  • Not Acknowledging messages from an event bus if got a Network or Infrastructure generic exception.
  • Get an HTTP/gRPC/OpenCensus status code from an error.
  • Implement multiple strategies when an specific (or generic) type of error was thrown in.
  • Fine-grained exception logging on infrastructure layer by using GetParentDescription() function.

Usage

HTTP status codes

Set an HTTP error code depending on the exception.

err := ddderr.NewNotFound("foo")
log.Print(err) // prints: "The resource foo was not found"

if err.IsNotFound() {
  log.Print(http.StatusNotFound) // prints: 404
  return
}

log.Print(http.StatusInternalServerError) // prints: 500

Or use the builtin HTTP utils:

err := ddderr.NewNotFound("foo")
log.Print(err) // prints: "The resource foo was not found"

// HttpError struct is ready to be marshaled using JSON encoding libs
//
// Function accepts the following optional params (specified on the RFC spec):
// - Type
// - Instance
httpErr := ddderr.NewHttpError("", "", err)
// Will output -> If errType param is empty, then HTTP status text is used as type
// (e.g. Not Found, Internal Server Error)
log.Print(httpErr.Type)
// Will output -> 404 as we got a NotFound error type
log.Print(httpErr.Status)
// Will output -> The resource foo was not found
log.Print(httpErr.Detail)

Domain generic exceptions

Create a generic domain exception when other domain errors don't fulfill your requirements.

err := ddderr.NewDomain("generic error title", "foo has returned a generic domain error")
log.Print(err) // prints: "foo has returned a generic domain error"

if err.IsDomain() {
  log.Print(http.StatusBadRequest) // prints: 400
  return
}

log.Print(http.StatusInternalServerError) // prints: 500

Infrastructure generic exceptions

Create a generic infrastructure exception when other infrastructure exceptions don't fulfill your requirements.

msgErr := errors.New("sarama: Apache kafka consumer error")
err := ddderr.NewInfrastructure("generic error title", "error while consuming message from queue").
	AttachParent(msgErr)
log.Print(err) // prints: "error while consuming message from queue"
log.Print(err.Parent()) // prints: "sarama: Apache kafka consumer error"

Implement multiple strategies depending on exception kind

Take an specific action depending on the exception kind.

esErr := errors.New("failed to connect to Elasticsearch host http://127.0.0.1:9300")

err := ddderr.NewRemoteCall("http://127.0.0.1:9300").
	AttachParent(esErr)
log.Print("infrastructure error: ", err)                       // prints "failed to call external resource [http://127.0.0.1:9300]"
log.Print("infrastructure error resource: ", err.Property())       // http://127.0.0.1:9300
log.Print("is domain error: ", err.IsDomain())                 // false
log.Print("is infrastructure error: ", err.IsInfrastructure()) // true
log.Print("infrastructure error parent: ", err.Parent())       // prints "failed to connect to Elasticsearch host http://127.0.0.1:9300"

if err.IsRemoteCall() {
    // implement retry and/or circuit breaker pattern(s)
}

See examples for more details.

Requirements

  • Go version >= 1.13

Documentation

Overview

Package ddderr -or DDD Error- is a generic domain-driven exception wrapper made for Go.

DDD Error aims to ease the lack of exception handling in The Go Programming Language by defining a wide selection of common exceptions which happen inside the domain and/or infrastructure layer(s).

DDD Error is dependency-free, it complies with Go's built-in error interface and avoids reflection to increase overall performance.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetHttpStatusCode

func GetHttpStatusCode(err Error) int

GetHttpStatusCode retrieves an HTTP status code from the given error

Types

type Error

type Error struct {
	// contains filtered or unexported fields
}

Error contains specific mechanisms useful for further error mapping and other specific use cases

func NewAlreadyExists

func NewAlreadyExists(resource string) Error

NewAlreadyExists creates an Error for Already Exists use cases

(description e.g. The resource foo was already created)

func NewDomain

func NewDomain(title, description string) Error

NewDomain creates an Error for Domain generic use cases

func NewInfrastructure

func NewInfrastructure(title, description string) Error

NewInfrastructure creates an Error for Infrastructure generic use cases

func NewInvalidFormat

func NewInvalidFormat(property string, formats ...string) Error

NewInvalidFormat creates an Error for Invalid Format use cases

(description e.g. The property foo has an invalid format, expected [x1, x2, xN])

func NewNotFound

func NewNotFound(resource string) Error

NewNotFound creates an Error for Not Found use cases

(description e.g. The resource foo was not found)

func NewOutOfRange

func NewOutOfRange(property string, a, b int) Error

NewOutOfRange creates an Error for Out of Range use cases

(description e.g. The property foo is out of range [A, B))

func NewRemoteCall

func NewRemoteCall(externalResource string) Error

NewRemoteCall creates an Error for network remote calls failing scenarios

(e.g. database connection failed, sync inter-service transaction failed over a networking problem)

func NewRequired

func NewRequired(property string) Error

NewRequired creates an Error for Required use cases

(description e.g. The property foo is required)

func (Error) Description

func (e Error) Description() string

Description retrieves a specific and detailed error message

func (Error) Error

func (e Error) Error() string

Error returns the error description

func (Error) IsAlreadyExists

func (e Error) IsAlreadyExists() bool

IsAlreadyExists checks if the error belongs to Already Exists error types

func (Error) IsDomain

func (e Error) IsDomain() bool

IsDomain checks if the error belongs to Domain error group

func (Error) IsInfrastructure

func (e Error) IsInfrastructure() bool

IsInfrastructure checks if the error belongs to Infrastructure error group

func (Error) IsInvalidFormat

func (e Error) IsInvalidFormat() bool

IsInvalidFormat checks if the error belongs to Invalid Format error types

func (Error) IsNotFound

func (e Error) IsNotFound() bool

IsNotFound checks if the error belongs to Not Found error types

func (Error) IsOutOfRange

func (e Error) IsOutOfRange() bool

IsOutOfRange checks if the error belongs to Out of Range error types

func (Error) IsRemoteCall

func (e Error) IsRemoteCall() bool

IsRemoteCall checks if the error belongs to Failed Remote Call error types

func (Error) IsRequired

func (e Error) IsRequired() bool

IsRequired checks if the error belongs to Required error types

func (Error) Kind

func (e Error) Kind() string

Kind retrieves the error type (e.g. NotFound, AlreadyExists)

func (Error) Parent

func (e Error) Parent() error

Parent returns the error parent

Note: Might return nil if parent was not specified

func (Error) Property

func (e Error) Property() string

Property returns the resource or field which contains the error

func (Error) SetDescription

func (e Error) SetDescription(description string) Error

SetDescription sets a specific and detailed error message

func (Error) SetKind

func (e Error) SetKind(kind string) Error

SetKind sets the specific error type (e.g. NotFound, AlreadyExists)

func (Error) SetParent added in v3.3.0

func (e Error) SetParent(err error) Error

SetParent sets a parent error to the given DDD error

func (Error) SetProperty

func (e Error) SetProperty(property string) Error

SetProperty sets the field or resource for an error

func (Error) SetStatus added in v3.1.0

func (e Error) SetStatus(status string) Error

SetStatus sets a system-owned status for the Error

func (Error) SetTitle

func (e Error) SetTitle(title string) Error

SetTitle sets a generic error message

func (Error) Status added in v3.1.0

func (e Error) Status() string

Status retrieves the status name of the Error owned by the system

func (Error) Title

func (e Error) Title() string

Title retrieves a generic error message

type HttpError

type HttpError struct {
	Type       string `json:"type,omitempty"`
	Title      string `json:"title,omitempty"`
	Status     string `json:"status,omitempty"`
	StatusCode int    `json:"status_code,omitempty"`
	Detail     string `json:"detail,omitempty"`
	Instance   string `json:"instance,omitempty"`
}

HttpError is an RFC-compliant HTTP protocol problem object.

For more information about the fields, please go to: https://datatracker.ietf.org/doc/html/rfc7807

func NewHttpError

func NewHttpError(errType, instance string, err error) HttpError

NewHttpError builds an HttpError from the given DDD error

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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