func IsNotExist(err error) bool {
	if os.IsNotExist(err) {
		return true
	}
	type notExist interface {
		NotExist() bool
	}
	n, ok := err.(notExist)
	if !ok {
		return false
	}
	return n.NotExist()
}
TODO: add a hybrid error interface having all possible methods which can
customize behavior by setting flags.
IsNotExist returns true when the error is related to "not found" or is
os.ErrNotExist. To be consistent with os.IsNotExist, the name of this
function is IsNotExist, not IsNotExistError.

If the error implements following interface, IsNotExist returns the return
value of NotExist method:

interface {
NotExist() bool
}
package core
import (
	"fmt"
	"os"
	"strings"
)
var (
	errPipeClosed = fmt.Errorf("the pipe is already closed")
)
type bulkErrors struct {
	errs []error
}
func (b *bulkErrors) append(err error) {
	b.errs = append(b.errs, err)
}
func (b *bulkErrors) returnError() error {
	switch len(b.errs) {
	case 0:
		return nil
	case 1:
		return b.errs[0]
	default:
		return b
	}
}
func (b *bulkErrors) Error() string {
	res := make([]string, len(b.errs))
	for i, e := range b.errs {
		res[i] = e.Error()
	}
	return `"` + strings.Join(res, `", "`) + `"`
}
func (b *bulkErrors) Fatal() bool {
	for _, e := range b.errs {
		if IsFatalError(e) {
			return true
		}
	}
	return false
}
func (b *bulkErrors) Temporary() bool {
	for _, e := range b.errs {
		if !IsTemporaryError(e) {
			return false
		}
	}
	return true
}
func IsFatalError(err error) bool {
	type fatal interface {
		Fatal() bool
	}
	if e, ok := err.(fatal); ok {
		return e.Fatal()
	}
	return false
}
type fatalError struct {
	err error
}
func (f *fatalError) Error() string {
	return f.err.Error()
}
func (f *fatalError) Fatal() bool {
	return true
}
func FatalError(err error) error {
	if err == nil {
		panic(fmt.Errorf("the error cannot be nil"))
	}
	return &fatalError{err: err}
}
func IsTemporaryError(err error) bool {
	type temporary interface {
		Temporary() bool
	}
	if e, ok := err.(temporary); ok {
		return e.Temporary()
	}
	return false
}
type temporaryError struct {
	err error
}
func (t *temporaryError) Error() string {
	return t.err.Error()
}
func (t *temporaryError) Temporary() bool {
	return true
}
func TemporaryError(err error) error {
	if err == nil {
		panic(fmt.Errorf("the error cannot be nil"))
	}
	return &temporaryError{err: err}
}