Deprecated: Function get_magic_quotes_gpc() is deprecated in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 99

Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 619

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1169

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176
8000 GitHub - dnozdrin/errdetail: Wrap multiple errors in one Go error type.
Nothing Special   »   [go: up one dir, main page]

Skip to content

dnozdrin/errdetail

Repository files navigation

errdetail logo

Errdetail

Enrich Go errors by context information.


Language License Codecov Coreportcard GitHub CI Go Reference Release

Description

Errdetail allows to add one or multiple details to an error. Each detail may contain the next optional fields:

Field Possible usage Example
domain a particular interest, activity, or type of knowledge user.management
code a unique code for a particular type of error validation_email_invalid_character
description a short, human-readable summary of the problem that should change from occurrence to occurrence of the problem email address must follow the format described in the RFC 5322
field a field where the error occurred, common for validation issues user.email
reason a human-readable explanation specific to this occurrence of the problem an invalid character has been detected in the provided sequence
meta arbitrary data required for the error explanation {"dummyField1":"dummyValue", "dummyField2":2}

With such approach it's possible to aggregate information about several errors into one type that implements the error interface.

Usage

Create a detailed error

err := errdetail.New(
    "bad request",
    errdetail.NewDetail(
        errdetail.WithDomain("user.auth"),
        errdetail.WithCode("invalid_email"),
        errdetail.WithDescription("email validation failed"),
        errdetail.WithField("user.email"),
        errdetail.WithReason("invalid character detected: \"#\""),
        errdetail.WithMeta(errdetail.Meta{
			"dummyField1": "dummyValue",
			"dummyField2": 2,
        }),
    )
)

Wrap existing error

err := errdetail.Wrap(
    errdetail.ErrInvalidArgument,
    "bad request",
    errdetail.NewDetail(
        errdetail.WithDomain("user.auth"),
        errdetail.WithCode("invalid_email"),
        errdetail.WithDescription("email validation failed"),
        errdetail.WithField("user.email"),
        errdetail.WithReason("invalid character detected: \"#\""),
        errdetail.WithMeta(errdetail.Meta{
            "dummyField1": "dummyValue",
            "dummyField2": 2,
        }),
    ),
    errdetail.NewDetail(
        errdetail.WithDomain("user.auth"),
        errdetail.WithCode("invalid_password"),
        errdetail.WithDescription("password validation failed"),
        errdetail.WithField("user.password"),
        errdetail.WithReason("password is empty"),
        errdetail.WithMeta(errdetail.Meta{
            "dummyField3": "hello world!",
            "dummyField4": 4,
        }),
    ),
)

Use provided error constructors

err := NewNotFound("discount not found", errdetail.NewDetail(errdetail.WithCode("order_discount_not_supported")))

Use predefined errors

func (a *Adapter) Get(ctx context.Context, id uuid.UUID) (Item, error) {
    if item, ok := a.storage.Get(ctx, id); !ok {
        return Item{}, errdetail.ErrNotFound
    }
    
    // ...
}

Transform errors details to a suitable presentation

type ErrorResponse struct {
    Error *Error `json:"error,omitempty"`
}

type Error struct {
    Status int `json:"status"`
    Title string `json:"title"`
    Code ResponseCode `json:"code"`
    Details []ErrorDetail `json:"details,omitempty"`
}

type ErrorDetail struct {
    Domain string `json:"domain,omitempty"`
    Reason string `json:"reason,omitempty"`
    Field string `json:"field,omitempty"`
    Description string `json:"description,omitempty"`
    Code string `json:"code,omitempty"`
}

func NewErrorResponse(err error) ErrorResponse {
    if err == nil {
        return ErrorResponse{}
    }
    
    var (
        status int
        title  string
        code   ResponseCode
    )
    
    switch {
    case errors.Is(err, errdetail.ErrInvalidArgument):
        status = http.StatusBadRequest
        title = errdetail.ErrInvalidArgument.Error()
        code = "INVALID_ARGUMENT"
	
    case errors.Is(err, errdetail.ErrNotFound):
        status = http.StatusNotFound
        title = errdetail.ErrNotFound.Error()
        code = "NOT_FOUND"
    
	// ...
    
    default:
        status = http.StatusInternalServerError
        title = "unknown"
        code = "UNKNOWN"
    }
    
    return ErrorResponse{
        Error: &Error{
            Code:    code,
            Title:   title,
            Status:  status,
            Details: extractDetails(err),
        },
    }
}

func extractDetails(err error) []ErrorDetail {
    extracted := errdetail.ExtractDetails(err)
    if len(extracted) == 0 {
        return nil
    }
    
    details := make([]ErrorDetail, len(extracted))
        for i := range extracted {
            details[i] = ErrorDetail{
            Domain:      extracted[i].Domain(),
            Reason:      extracted[i].Reason(),
            Field:       extracted[i].Field(),
            Description: extracted[i].Description(),
            Code:        extracted[i].Code(),
        }
    }
    
    return details
}

ErrorResponse encoded to JSON:

{
  "error": {
    "status": 400,
    "title": "invalid argument",
    "code": "INVALID_ARGUMENT",
    "details": [
      {
        "domain": "user.auth",
        "code": "invalid_email",
        "description": "email validation failed",
        "field": "user.email",
        "reason": "invalid character detected: \"#\"",
        "meta": {
          "link": "https://example.com",
          "translations": {
            "en": "Hello world!",
            "ua": "Привіт, світе!"
          }
        }
      },
      {
        "domain": "user.auth",
        "code": "invalid_password",
        "description": "password validation failed",
        "field": "user.password",
        "reason": "password is empty"
      }
    ]
  }
}

For further details see examples and reference.

Contributing

For contribution guidelines check CONTRIBUTING.md

About

Wrap multiple errors in one Go error type.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Languages

0