+
Skip to content

gildas/go-errors

Repository files navigation

go-errors

GoVersion GoDoc License Report

master Test codecov

dev Test codecov

This is a library for handling errors in Go language.

Usage

This package combines Go standard errors package and github.com/pkg/errors.

All funcs from both packages are available.

On top of them, I added some sentinels for common errors I need all the time.

All sentinels are from the same type which contains various information. Whenever a sentinel is used, a StackTrace is also generated.

Here is how to use the errors:

func findme(stuff map[string]string, key string) (string, error) {
    if value, found := stuff[key]; found {
        return value, nil
    }
    return "", errors.NotFound.With("key", key)
}

func main() {
    var allstuff[string]string
    //...
    value, err := findme("key1")
    if errors.Is(err, errors.NotFound) {
        fmt.Fprintf(os.Stderr, "Error: %+v", err)
        // This should print the error its wrapped content and a StackTrace.
    }
}

If you plan to do something with the content of the error, you would try that:

func main() {
    var allstuff[string]string
    //...
    value, err := findme("key1")
    if errors.Is(err, errors.NotFound) {
        var details *errors.Error
        if errors.As(err, &details) {
            fmt.Fprintf(os.Stderr, "Could not find %s", details.What)
        }
    }
}

Note: You should not use var details errors.Error, use the pointer version var details *errors.Error instead.

When several errors.Error are chained up, this can be used to extract the ones you want:

func main() {
    var allstuff[string]string
    //...
    value, err := findme("key1")
    if errors.Is(err, errors.NotFound) {
        details := errors.NotFound.Clone()
        if errors.As(err, &details) {
            fmt.Fprintf(os.Stderr, "Could not find %s", details.What)
        }
    }
}

To return an HTTP Status as an error, you could do this:

func doit() error {
    req, err := http.NewRequest(http.MethodGet, "http://www.acme.org")
    if err != nil {
        return errors.WithStack(err)
    }
    httpclient := http.DefaultClient()
    res, err := httpclient.Do(req)
    if err != nil {
        return errors.WithStack(err)
    }
    if res.StatusCode >= 400 {
        return errors.FromHTTPStatusCode(res.StatusCode)
    }
    return nil
}

func main() {
    err := doit()
    if (errors.Is(err, errors.HTTPBadRequest)) {
        // do something
    }
    // do something else
}

You can chain multiple errors together (See Example):

func doit() error {
    // ... some processing
    var urlError *url.Error // errors from the net/url package

    return errors.WrapErrors(err, errors.NotFound.With("key", "key1"), urlError)
}

You can also use a errors.MultiError to collect multiple errors together (See Example):

me := errors.MultiError{}
me.Append(errors.NotFound.With("key", "key1"))
me.Append(errors.NotFound.With("key", "key2"))
fmt.Println(me.AsError())

Finally, errors.Error supports JSON serialization:

err := errors.InvalidType.With("bogus")
payload, jerr := json.Marshal(err)
// ...

About

Go Error management

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载