Commit 7e9d3221 authored by Kirill Smelkov's avatar Kirill Smelkov

xerr: Convert documentation to Go style + package-level description

I was too used to my old Python habit while originally writing this.
Using the occasion add package-level description which outlines the
package to a user.
parent 66edb630
// Copyright (C) 2015-2017 Nexedi SA and Contributors.
// Copyright (C) 2015-2018 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
......@@ -17,7 +17,48 @@
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
// Package xerr provides addons for error-handling
// Package xerr provides addons for error-handling.
//
//
// Error context
//
// Context and Contextf are handy to concisely add context to returned error,
// for example:
//
// func myfunc(arg1, arg2 string) (..., err error) {
// defer xerr.Contextf(&error, "doing something (%s, %s)", arg1, arg2)
// ...
//
// which will, if returned error is !nil, wrap it with the following prefix:
//
// "doing something (%s, %s):" % (arg1, arg2)
//
// The original unwrapped error will be still accessible as the cause of
// returned error. Please see package github.com/pkg/errors for details on
// this topic.
//
//
// Error vector
//
// Sometimes there are several operations performed and we want to collect
// errors from them all. For this Errorv could be used which is vector of
// errors and at the same time an error itself. After collecting it is possible
// to extract resulting error from the vector in canonical form with
// Errorv.Err. Errorv also provides handy ways to append errors to the vector
// - see Errorv.Append* for details.
//
// For convenience Merge could be used to concisely construct error vector
// from !nil errors and extract its canonical form in one line, for example:
//
// err1 := op1(...)
// err2 := op2(...)
// err3 := op3(...)
//
// err := xerr.Merge(err1, err2, err3)
// return err
//
// There is also First counterpart to Merge, which returns only first !nil
// error.
package xerr
import (
......@@ -26,9 +67,14 @@ import (
"github.com/pkg/errors"
)
// error merging multiple errors (e.g. after collecting them from several parallel workers)
// Errorv is error vector merging multiple errors (e.g. after collecting them from several parallel workers).
type Errorv []error
// Error returns string representation of error vector.
//
// - "" if len(errv)==0
// - errv[0].Error() if len(errv)==1
// - "<n> errors:\n" + string representation of every error on separate line, otherwise.
func (errv Errorv) Error() string {
switch len(errv) {
case 0:
......@@ -44,12 +90,12 @@ func (errv Errorv) Error() string {
return msg
}
// append err to error vector
// Append appends err to error vector.
func (errv *Errorv) Append(err error) {
*errv = append(*errv, err)
}
// append err to error vector, but only if err != nil
// Appendif appends err to error vector if err != nil.
func (errv *Errorv) Appendif(err error) {
if err == nil {
return
......@@ -57,15 +103,16 @@ func (errv *Errorv) Appendif(err error) {
errv.Append(err)
}
// append formatted error string
// Appendf appends formatted error string.
func (errv *Errorv) Appendf(format string, a ...interface{}) {
errv.Append(fmt.Errorf(format, a...))
}
// Err returns error in canonical form accumulated in error vector
// - nil if len(errv)==0
// - errv[0] if len(errv)==1 // XXX is this good idea?
// - errv otherwise
// Err returns error in canonical form accumulated in error vector.
//
// - nil if len(errv)==0
// - errv[0] if len(errv)==1 // XXX is this good idea?
// - errv otherwise
func (errv Errorv) Err() error {
switch len(errv) {
case 0:
......@@ -77,11 +124,13 @@ func (errv Errorv) Err() error {
}
}
// Merge merges non-nil errors into one error
// Merge merges non-nil errors into one error.
//
// it returns:
// - nil if all errors are nil
// - single error if there is only one non-nil error
// - Errorv with non-nil errors if there is more than one non-nil error
//
// - nil if all errors are nil
// - single error if there is only one non-nil error
// - Errorv with non-nil errors if there is more than one non-nil error
func Merge(errv ...error) error {
ev := Errorv{}
for _, err := range errv {
......@@ -90,7 +139,7 @@ func Merge(errv ...error) error {
return ev.Err()
}
// First returns first non-nil error, or nil if there is no errors
// First returns first non-nil error, or nil if there is no errors.
func First(errv ...error) error {
for _, err := range errv {
if err != nil {
......@@ -102,14 +151,15 @@ func First(errv ...error) error {
// ----------------------------------------
// Context provides error context to be automatically added on error return
// to work as intended it should be called under defer like this:
// Context provides error context to be automatically added on error return.
//
// Intended to be used under defer like this:
//
// func myfunc(...) (..., err error) {
// defer xerr.Context(&err, "error context")
// ...
//
// it is also possible to use Context directly to add context to an error if it
// It is also possible to use Context directly to add context to an error if it
// is non-nil:
//
// ..., myerr := f()
......@@ -130,7 +180,8 @@ func Context(errp *error, context string) {
*errp = errors.WithMessage(*errp, context)
}
// Contextf provides formatted error context to be automatically added on error return
// Contextf provides formatted error context to be automatically added on error return.
//
// Contextf is formatted analog of Context. Please see Context for details on how to use.
func Contextf(errp *error, format string, argv ...interface{}) {
if *errp == nil {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment