Skip to content
/ errors Public

Drop in replacement for standard go errors and github.com/pkg/errors

License

Notifications You must be signed in to change notification settings

axkit/errors

Repository files navigation

errors GoDoc Build Status Coverage Status Go Report Card

errors

The errors package provides an enterprise approach of error handling. Drop in replacement of standard errors package.

Motivation

Make errors helpful for quick problem localization. Reduce amount of emails to the helpdesk due to better explained error reason.

Requirements

  • Wrapping: enhance original error message with context specific one;
  • Capture the calling stack;
  • Cut calling stack related to the HTTP framework;
  • Enhance error with key/value pairs, later could be written into structurized log;
  • Enhance error with the code what can be refered in documentation. (i.g. ORA-0600 in Oracle);
  • Enhance error with severity level;
  • Support different JSON representation for server and client;
  • Possibility to mark any error as protected. It will not be presented in client's JSON.
  • Notify SRE if needed.

Installation

go get -u github.com/axkit/error

Usage Examples

Catch and Enhance Standard Go Error

func (srv *CustomerService)WriteJSON(w io.Writer, c *Customer) (int, error) {

    buf, err := json.Marshal(src)
    if err != nil {
        return 0, errors.Catch(err).Critical().Set("customer", c).StatusCode(500).Msg("internal error")
    }

    n, err := w.Write(buf)
    if err != nil {
        // Level is Tiny by default. 
        return 0, errors.Catch(err).StatusCode(500).Msg("writing to stream failed").Code("APP-0001")
    }
     
    return n, nil  
}

Catch and Enhance Already Catched Error

func AllowedProductAmount(balance, price int) (int, error) {

    res, err := Calc(balance, price)
    if err != nil {
        return 0, errors.Catch(err).SetPairs("balance", balance, "price", price).Msg("no allowed products")
    }

    return res, nil
}


func Calc(a, b int) (int, error) {

    if b == 0 {
        return 0, errors.New("divizion by zero").Critical()
    }

    return a/b, nil
}

Recatch NotFound Error Conditionally

There is a special function errors.IsNotFound() that returns true error has StatusCode = 404 or created using errors.NotFound().

func (srv *CustomerService)AcceptPayment(customerID int, paymentAmount int64) error {

    c, err := srv.repo.CustomerByID(id)
    if err != nil {
        if errors.IsNotFound(err) {
            return nil, errors.Catch(err).Medium().Msg("invalid customer")
        }
        return return nil, errors.Catch(err).Critical().Msg("internal error")
    }

    return c, nil
}

func (srv *CustomerService)CustomerByID(id int) (*Customer, error) {

    c, ok := srv.repo.CustomerByID(id)
    if !ok {
        return nil, errors.NotFound("customer not found").Set("id", id)
    }

    return c, nil
}

Write Error Responce to Client

    err := doSmth()
    
    // err is standard error  
    fmt.Println(errors.ToClientJSON(err))

    // Output:
    {"msg":"result of Error() method"}

Write Error Responce to Server Log

Send Alarm to SRE

License

MIT

About

Drop in replacement for standard go errors and github.com/pkg/errors

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages