add error pkg

This commit is contained in:
Livio Amstutz
2020-03-18 15:45:24 +01:00
parent f8fdbb0611
commit 238347ddfb
30 changed files with 978 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
package errors
import "fmt"
var (
_ AlreadyExists = (*AlreadyExistsError)(nil)
_ Error = (*AlreadyExistsError)(nil)
)
type AlreadyExists interface {
error
IsAlreadyExists()
}
type AlreadyExistsError struct {
*CaosError
}
func ThrowAlreadyExists(parent error, id, message string) error {
return &AlreadyExistsError{createCaosError(parent, id, message)}
}
func ThrowAlreadyExistsf(parent error, id, format string, a ...interface{}) error {
return &AlreadyExistsError{createCaosError(parent, id, fmt.Sprintf(format, a...))}
}
func (err *AlreadyExistsError) IsAlreadyExists() {}
func IsErrorAlreadyExists(err error) bool {
_, ok := err.(AlreadyExists)
return ok
}

View File

@@ -0,0 +1,34 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestAlreadyExistsError(t *testing.T) {
var alreadyExistsError interface{}
alreadyExistsError = new(caos_errs.AlreadyExistsError)
_, ok := alreadyExistsError.(caos_errs.AlreadyExists)
assert.True(t, ok)
}
func TestThrowAlreadyExistsf(t *testing.T) {
err := caos_errs.ThrowAlreadyExistsf(nil, "id", "msg")
_, ok := err.(*caos_errs.AlreadyExistsError)
assert.True(t, ok)
}
func TestIsErrorAlreadyExists(t *testing.T) {
err := caos_errs.ThrowAlreadyExists(nil, "id", "msg")
ok := caos_errs.IsErrorAlreadyExists(err)
assert.True(t, ok)
err = errors.New("Already Exists!")
ok = caos_errs.IsErrorAlreadyExists(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,48 @@
package errors
import (
"fmt"
)
var _ Error = (*CaosError)(nil)
type CaosError struct {
Parent error
Message string
ID string
}
func ThrowError(parent error, id, message string) error {
return createCaosError(parent, id, message)
}
func createCaosError(parent error, id, message string) *CaosError {
return &CaosError{
Parent: parent,
ID: id,
Message: message,
}
}
func (err *CaosError) Error() string {
if err.Parent != nil {
return fmt.Sprintf("ID=%s Message=%s Parent=(%v)", err.ID, err.Message, err.Parent)
}
return fmt.Sprintf("ID=%s Message=%s", err.ID, err.Message)
}
func (err *CaosError) Unwrap() error {
return err.GetParent()
}
func (err *CaosError) GetParent() error {
return err.Parent
}
func (err *CaosError) GetMessage() string {
return err.Message
}
func (err *CaosError) GetID() string {
return err.ID
}

View File

@@ -0,0 +1,19 @@
package errors_test
import (
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestErrorMethod(t *testing.T) {
err := caos_errs.ThrowError(nil, "id", "msg")
expected := "ID=id Message=msg"
assert.Equal(t, expected, err.Error())
err = caos_errs.ThrowError(err, "subID", "subMsg")
subExptected := "ID=subID Message=subMsg Parent=(ID=id Message=msg)"
assert.Equal(t, subExptected, err.Error())
}

View File

@@ -0,0 +1,34 @@
package errors
import (
"fmt"
)
var (
_ DeadlineExceeded = (*DeadlineExceededError)(nil)
_ Error = (*DeadlineExceededError)(nil)
)
type DeadlineExceeded interface {
error
IsDeadlineExceeded()
}
type DeadlineExceededError struct {
*CaosError
}
func ThrowDeadlineExceeded(parent error, id, message string) error {
return &DeadlineExceededError{createCaosError(parent, id, message)}
}
func ThrowDeadlineExceededf(parent error, id, format string, a ...interface{}) error {
return ThrowDeadlineExceeded(parent, id, fmt.Sprintf(format, a...))
}
func (err *DeadlineExceededError) IsDeadlineExceeded() {}
func IsDeadlineExceeded(err error) bool {
_, ok := err.(DeadlineExceeded)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestDeadlineExceededError(t *testing.T) {
var err interface{}
err = new(caos_errs.DeadlineExceededError)
_, ok := err.(caos_errs.DeadlineExceeded)
assert.True(t, ok)
}
func TestThrowDeadlineExceededf(t *testing.T) {
err := caos_errs.ThrowDeadlineExceededf(nil, "id", "msg")
_, ok := err.(*caos_errs.DeadlineExceededError)
assert.True(t, ok)
}
func TestIsDeadlineExceeded(t *testing.T) {
err := caos_errs.ThrowDeadlineExceeded(nil, "id", "msg")
ok := caos_errs.IsDeadlineExceeded(err)
assert.True(t, ok)
err = errors.New("I am found!")
ok = caos_errs.IsDeadlineExceeded(err)
assert.False(t, ok)
}

18
internal/errors/error.go Normal file
View File

@@ -0,0 +1,18 @@
package errors
import (
"strings"
)
// Error is a stdlib error extension.
// It contains parameters to identify errors through all application layers
type Error interface {
GetParent() error
GetMessage() string
GetID() string
}
// Contains compares the error message with needle
func Contains(err error, needle string) bool {
return err != nil && strings.Contains(err.Error(), needle)
}

View File

@@ -0,0 +1,19 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errors "github.com/caos/utils/errors"
)
func TestContains(t *testing.T) {
err := errors.New("hello world")
world := caos_errors.Contains(err, "hello")
assert.True(t, world)
mars := caos_errors.Contains(err, "mars")
assert.False(t, mars)
}

View File

@@ -0,0 +1,34 @@
package errors
import (
"fmt"
)
var (
_ {{.ErrorName}} = (*{{.ErrorName}}Error)(nil)
_ Error = (*{{.ErrorName}}Error)(nil)
)
type {{.ErrorName}} interface {
error
Is{{.ErrorName}}()
}
type {{.ErrorName}}Error struct {
*CaosError
}
func Throw{{.ErrorName}}(parent error, id, message string) error {
return &{{.ErrorName}}Error{createCaosError(parent, id, message)}
}
func Throw{{.ErrorName}}f(parent error, id, format string, a ...interface{}) error {
return Throw{{.ErrorName}}(parent, id, fmt.Sprintf(format, a...))
}
func (err *{{.ErrorName}}Error) Is{{.ErrorName}}() {}
func Is{{.ErrorName}}(err error) bool {
_, ok := err.({{.ErrorName}})
return ok
}

View File

@@ -0,0 +1,75 @@
//go generate
package main
import (
"flag"
"fmt"
"html/template"
"log"
"os"
"strings"
)
func main() {
errorName := readErrorName()
errorName = validateErrorName(errorName)
data := &Data{
ErrorName: errorName,
}
errorFile := data.createFile("error.go.tmpl")
data.createTemplate("error.go.tmpl", errorFile)
if err := errorFile.Close(); err != nil {
log.Fatal(err)
}
testFile := data.createFile("error_test.go.tmpl")
data.createTemplate("error_test.go.tmpl", testFile)
if err := testFile.Close(); err != nil {
log.Fatal(err)
}
fmt.Print(`
!!!!!
Add status mapping in grpc/errors/caos_errors.go
!!!!!`)
}
type Data struct {
ErrorName string
}
func (data *Data) createFile(tmplName string) *os.File {
filename := strings.Replace(tmplName, "error", strings.ToLower(data.ErrorName), 1)
filename = filename[:len(filename)-5]
filePath := fmt.Sprintf("../%s", filename)
file, err := os.Create(filePath)
if err != nil {
log.Fatalf("unable to create file (%s): %v", filePath, err)
}
return file
}
func (data *Data) createTemplate(templateName string, file *os.File) {
tmpl := template.Must(template.New(templateName).ParseFiles(templateName))
if err := tmpl.Execute(file, data); err != nil {
log.Fatal("unable to execute tmpl: ", err)
}
}
func readErrorName() (errorName string) {
flag.StringVar(&errorName, "Name", "", "Type of the error (e.g. Internal)")
flag.Parse()
return errorName
}
func validateErrorName(errorName string) string {
if errorName == "" {
log.Fatal("pass argument name")
}
if strings.Contains(errorName, " ") || strings.Contains(errorName, ".") {
log.Fatal("name cannot contain spaces or points")
}
return strings.Title(errorName)
}

View File

@@ -0,0 +1,5 @@
type {{.ErrorName}} interface {
error
Is{{.ErrorName}}()
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func Test{{.ErrorName}}Error(t *testing.T) {
var err interface{}
err = new(caos_errs.{{.ErrorName}}Error)
_, ok := err.(caos_errs.{{.ErrorName}})
assert.True(t, ok)
}
func TestThrow{{.ErrorName}}f(t *testing.T) {
err := caos_errs.Throw{{.ErrorName}}f(nil, "id", "msg")
_, ok := err.(*caos_errs.{{.ErrorName}}Error)
assert.True(t, ok)
}
func TestIs{{.ErrorName}}(t *testing.T) {
err := caos_errs.Throw{{.ErrorName}}(nil, "id", "msg")
ok := caos_errs.Is{{.ErrorName}}(err)
assert.True(t, ok)
err = errors.New("I am found!")
ok = caos_errs.Is{{.ErrorName}}(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,34 @@
package errors
import (
"fmt"
)
var (
_ Internal = (*InternalError)(nil)
_ Error = (*InternalError)(nil)
)
type Internal interface {
error
IsInternal()
}
type InternalError struct {
*CaosError
}
func ThrowInternal(parent error, id, message string) error {
return &InternalError{createCaosError(parent, id, message)}
}
func ThrowInternalf(parent error, id, format string, a ...interface{}) error {
return ThrowInternal(parent, id, fmt.Sprintf(format, a...))
}
func (err *InternalError) IsInternal() {}
func IsInternal(err error) bool {
_, ok := err.(Internal)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestInternalError(t *testing.T) {
var err interface{}
err = new(caos_errs.InternalError)
_, ok := err.(caos_errs.Internal)
assert.True(t, ok)
}
func TestThrowInternalf(t *testing.T) {
err := caos_errs.ThrowInternalf(nil, "id", "msg")
_, ok := err.(*caos_errs.InternalError)
assert.True(t, ok)
}
func TestIsInternal(t *testing.T) {
err := caos_errs.ThrowInternal(nil, "id", "msg")
ok := caos_errs.IsInternal(err)
assert.True(t, ok)
err = errors.New("I am found!")
ok = caos_errs.IsInternal(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,32 @@
package errors
import "fmt"
var (
_ InvalidArgument = (*InvalidArgumentError)(nil)
_ Error = (*InvalidArgumentError)(nil)
)
type InvalidArgument interface {
error
IsInvalidArgument()
}
type InvalidArgumentError struct {
*CaosError
}
func ThrowInvalidArgument(parent error, id, message string) error {
return &InvalidArgumentError{createCaosError(parent, id, message)}
}
func ThrowInvalidArgumentf(parent error, id, format string, a ...interface{}) error {
return ThrowInvalidArgument(parent, id, fmt.Sprintf(format, a...))
}
func (err *InvalidArgumentError) IsInvalidArgument() {}
func IsErrorInvalidArgument(err error) bool {
_, ok := err.(InvalidArgument)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestInvalidArgumentError(t *testing.T) {
var invalidArgumentError interface{}
invalidArgumentError = new(caos_errs.InvalidArgumentError)
_, ok := invalidArgumentError.(caos_errs.InvalidArgument)
assert.True(t, ok)
}
func TestThrowInvalidArgumentf(t *testing.T) {
err := caos_errs.ThrowInvalidArgumentf(nil, "id", "msg")
_, ok := err.(*caos_errs.InvalidArgumentError)
assert.True(t, ok)
}
func TestIsErrorInvalidArgument(t *testing.T) {
err := caos_errs.ThrowInvalidArgument(nil, "id", "msg")
ok := caos_errs.IsErrorInvalidArgument(err)
assert.True(t, ok)
err = errors.New("I am invalid!")
ok = caos_errs.IsErrorInvalidArgument(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,27 @@
package errors
import "fmt"
type NotFound interface {
error
IsNotFound()
}
type NotFoundError struct {
*CaosError
}
func ThrowNotFound(parent error, id, message string) error {
return &NotFoundError{createCaosError(parent, id, message)}
}
func ThrowNotFoundf(parent error, id, format string, a ...interface{}) error {
return ThrowNotFound(parent, id, fmt.Sprintf(format, a...))
}
func (err *NotFoundError) IsNotFound() {}
func IsNotFound(err error) bool {
_, ok := err.(NotFound)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestNotFoundError(t *testing.T) {
var notFoundError interface{}
notFoundError = new(caos_errs.NotFoundError)
_, ok := notFoundError.(caos_errs.NotFound)
assert.True(t, ok)
}
func TestThrowNotFoundf(t *testing.T) {
err := caos_errs.ThrowNotFoundf(nil, "id", "msg")
_, ok := err.(*caos_errs.NotFoundError)
assert.True(t, ok)
}
func TestIsNotFound(t *testing.T) {
err := caos_errs.ThrowNotFound(nil, "id", "msg")
ok := caos_errs.IsNotFound(err)
assert.True(t, ok)
err = errors.New("I am found!")
ok = caos_errs.IsNotFound(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,34 @@
package errors
import (
"fmt"
)
var (
_ PermissionDenied = (*PermissionDeniedError)(nil)
_ Error = (*PermissionDeniedError)(nil)
)
type PermissionDenied interface {
error
IsPermissionDenied()
}
type PermissionDeniedError struct {
*CaosError
}
func ThrowPermissionDenied(parent error, id, message string) error {
return &PermissionDeniedError{createCaosError(parent, id, message)}
}
func ThrowPermissionDeniedf(parent error, id, format string, a ...interface{}) error {
return ThrowPermissionDenied(parent, id, fmt.Sprintf(format, a...))
}
func (err *PermissionDeniedError) IsPermissionDenied() {}
func IsPermissionDenied(err error) bool {
_, ok := err.(PermissionDenied)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestPermissionDeniedError(t *testing.T) {
var err interface{}
err = new(caos_errs.PermissionDeniedError)
_, ok := err.(caos_errs.PermissionDenied)
assert.True(t, ok)
}
func TestThrowPermissionDeniedf(t *testing.T) {
err := caos_errs.ThrowPermissionDeniedf(nil, "id", "msg")
_, ok := err.(*caos_errs.PermissionDeniedError)
assert.True(t, ok)
}
func TestIsPermissionDenied(t *testing.T) {
err := caos_errs.ThrowPermissionDenied(nil, "id", "msg")
ok := caos_errs.IsPermissionDenied(err)
assert.True(t, ok)
err = errors.New("I am found!")
ok = caos_errs.IsPermissionDenied(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,34 @@
package errors
import (
"fmt"
)
var (
_ PreconditionFailed = (*PreconditionFailedError)(nil)
_ Error = (*PreconditionFailedError)(nil)
)
type PreconditionFailed interface {
error
IsPreconditionFailed()
}
type PreconditionFailedError struct {
*CaosError
}
func ThrowPreconditionFailed(parent error, id, message string) error {
return &PreconditionFailedError{createCaosError(parent, id, message)}
}
func ThrowPreconditionFailedf(parent error, id, format string, a ...interface{}) error {
return ThrowPreconditionFailed(parent, id, fmt.Sprintf(format, a...))
}
func (err *PreconditionFailedError) IsPreconditionFailed() {}
func IsPreconditionFailed(err error) bool {
_, ok := err.(PreconditionFailed)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestPreconditionFailedError(t *testing.T) {
var err interface{}
err = new(caos_errs.PreconditionFailedError)
_, ok := err.(caos_errs.PreconditionFailed)
assert.True(t, ok)
}
func TestThrowPreconditionFailedf(t *testing.T) {
err := caos_errs.ThrowPreconditionFailedf(nil, "id", "msg")
_, ok := err.(*caos_errs.PreconditionFailedError)
assert.True(t, ok)
}
func TestIsPreconditionFailed(t *testing.T) {
err := caos_errs.ThrowPreconditionFailed(nil, "id", "msg")
ok := caos_errs.IsPreconditionFailed(err)
assert.True(t, ok)
err = errors.New("Precondition failed!")
ok = caos_errs.IsPreconditionFailed(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,34 @@
package errors
import (
"fmt"
)
var (
_ Unauthenticated = (*UnauthenticatedError)(nil)
_ Error = (*UnauthenticatedError)(nil)
)
type Unauthenticated interface {
error
IsUnauthenticated()
}
type UnauthenticatedError struct {
*CaosError
}
func ThrowUnauthenticated(parent error, id, message string) error {
return &UnauthenticatedError{createCaosError(parent, id, message)}
}
func ThrowUnauthenticatedf(parent error, id, format string, a ...interface{}) error {
return ThrowUnauthenticated(parent, id, fmt.Sprintf(format, a...))
}
func (err *UnauthenticatedError) IsUnauthenticated() {}
func IsUnauthenticated(err error) bool {
_, ok := err.(Unauthenticated)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestUnauthenticatedError(t *testing.T) {
var err interface{}
err = new(caos_errs.UnauthenticatedError)
_, ok := err.(caos_errs.Unauthenticated)
assert.True(t, ok)
}
func TestThrowUnauthenticatedf(t *testing.T) {
err := caos_errs.ThrowUnauthenticatedf(nil, "id", "msg")
_, ok := err.(*caos_errs.UnauthenticatedError)
assert.True(t, ok)
}
func TestIsUnauthenticated(t *testing.T) {
err := caos_errs.ThrowUnauthenticated(nil, "id", "msg")
ok := caos_errs.IsUnauthenticated(err)
assert.True(t, ok)
err = errors.New("I am found!")
ok = caos_errs.IsUnauthenticated(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,34 @@
package errors
import (
"fmt"
)
var (
_ Unavailable = (*UnavailableError)(nil)
_ Error = (*UnavailableError)(nil)
)
type Unavailable interface {
error
IsUnavailable()
}
type UnavailableError struct {
*CaosError
}
func ThrowUnavailable(parent error, id, message string) error {
return &UnavailableError{createCaosError(parent, id, message)}
}
func ThrowUnavailablef(parent error, id, format string, a ...interface{}) error {
return ThrowUnavailable(parent, id, fmt.Sprintf(format, a...))
}
func (err *UnavailableError) IsUnavailable() {}
func IsUnavailable(err error) bool {
_, ok := err.(Unavailable)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestUnavailableError(t *testing.T) {
var err interface{}
err = new(caos_errs.UnavailableError)
_, ok := err.(caos_errs.Unavailable)
assert.True(t, ok)
}
func TestThrowUnavailablef(t *testing.T) {
err := caos_errs.ThrowUnavailablef(nil, "id", "msg")
_, ok := err.(*caos_errs.UnavailableError)
assert.True(t, ok)
}
func TestIsUnavailable(t *testing.T) {
err := caos_errs.ThrowUnavailable(nil, "id", "msg")
ok := caos_errs.IsUnavailable(err)
assert.True(t, ok)
err = errors.New("I am found!")
ok = caos_errs.IsUnavailable(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,34 @@
package errors
import (
"fmt"
)
var (
_ Unimplemented = (*UnimplementedError)(nil)
_ Error = (*UnimplementedError)(nil)
)
type Unimplemented interface {
error
IsUnimplemented()
}
type UnimplementedError struct {
*CaosError
}
func ThrowUnimplemented(parent error, id, message string) error {
return &UnimplementedError{createCaosError(parent, id, message)}
}
func ThrowUnimplementedf(parent error, id, format string, a ...interface{}) error {
return ThrowUnimplemented(parent, id, fmt.Sprintf(format, a...))
}
func (err *UnimplementedError) IsUnimplemented() {}
func IsUnimplemented(err error) bool {
_, ok := err.(Unimplemented)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestUnimplementedError(t *testing.T) {
var unimplementedError interface{}
unimplementedError = new(caos_errs.UnimplementedError)
_, ok := unimplementedError.(caos_errs.Unimplemented)
assert.True(t, ok)
}
func TestThrowUnimplementedf(t *testing.T) {
err := caos_errs.ThrowUnimplementedf(nil, "id", "msg")
_, ok := err.(*caos_errs.UnimplementedError)
assert.True(t, ok)
}
func TestIsUnimplemented(t *testing.T) {
err := caos_errs.ThrowUnimplemented(nil, "id", "msg")
ok := caos_errs.IsUnimplemented(err)
assert.True(t, ok)
err = errors.New("I am found!")
ok = caos_errs.IsUnimplemented(err)
assert.False(t, ok)
}

View File

@@ -0,0 +1,34 @@
package errors
import (
"fmt"
)
var (
_ Unknown = (*UnknownError)(nil)
_ Error = (*UnknownError)(nil)
)
type Unknown interface {
error
IsUnknown()
}
type UnknownError struct {
*CaosError
}
func ThrowUnknown(parent error, id, message string) error {
return &UnknownError{createCaosError(parent, id, message)}
}
func ThrowUnknownf(parent error, id, format string, a ...interface{}) error {
return ThrowUnknown(parent, id, fmt.Sprintf(format, a...))
}
func (err *UnknownError) IsUnknown() {}
func IsUnknown(err error) bool {
_, ok := err.(Unknown)
return ok
}

View File

@@ -0,0 +1,33 @@
package errors_test
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
caos_errs "github.com/caos/utils/errors"
)
func TestUnknownError(t *testing.T) {
var err interface{}
err = new(caos_errs.UnknownError)
_, ok := err.(caos_errs.Unknown)
assert.True(t, ok)
}
func TestThrowUnknownf(t *testing.T) {
err := caos_errs.ThrowUnknownf(nil, "id", "msg")
_, ok := err.(*caos_errs.UnknownError)
assert.True(t, ok)
}
func TestIsUnknown(t *testing.T) {
err := caos_errs.ThrowUnknown(nil, "id", "msg")
ok := caos_errs.IsUnknown(err)
assert.True(t, ok)
err = errors.New("I am found!")
ok = caos_errs.IsUnknown(err)
assert.False(t, ok)
}