Use error interfaces for content/metadata
These interfaces allow us to preserve both the checking of error "cause" as well as messages returned from the gRPC API so that the client gets full error reason instead of a default "metadata: not found" in the case of a missing image. Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com>
This commit is contained in:
parent
f5c587c1f7
commit
e10a9aff7d
@ -7,26 +7,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrNotFound is returned when an item is not found.
|
|
||||||
//
|
|
||||||
// Use IsNotFound(err) to detect this condition.
|
|
||||||
ErrNotFound = errors.New("content: not found")
|
|
||||||
|
|
||||||
// ErrExists is returned when something exists when it may not be expected.
|
|
||||||
//
|
|
||||||
// Use IsExists(err) to detect this condition.
|
|
||||||
ErrExists = errors.New("content: exists")
|
|
||||||
|
|
||||||
// ErrLocked is returned when content is actively being uploaded, this
|
|
||||||
// indicates that another process is attempting to upload the same content.
|
|
||||||
//
|
|
||||||
// Use IsLocked(err) to detect this condition.
|
|
||||||
ErrLocked = errors.New("content: locked")
|
|
||||||
|
|
||||||
bufPool = sync.Pool{
|
bufPool = sync.Pool{
|
||||||
New: func() interface{} {
|
New: func() interface{} {
|
||||||
return make([]byte, 1<<20)
|
return make([]byte, 1<<20)
|
||||||
@ -106,15 +89,3 @@ type Store interface {
|
|||||||
Ingester
|
Ingester
|
||||||
Provider
|
Provider
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsNotFound(err error) bool {
|
|
||||||
return errors.Cause(err) == ErrNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsExists(err error) bool {
|
|
||||||
return errors.Cause(err) == ErrExists
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsLocked(err error) bool {
|
|
||||||
return errors.Cause(err) == ErrLocked
|
|
||||||
}
|
|
||||||
|
120
content/errors.go
Normal file
120
content/errors.go
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
package content
|
||||||
|
|
||||||
|
type contentExistsErr struct {
|
||||||
|
desc string
|
||||||
|
}
|
||||||
|
|
||||||
|
type contentNotFoundErr struct {
|
||||||
|
desc string
|
||||||
|
}
|
||||||
|
|
||||||
|
type contentLockedErr struct {
|
||||||
|
desc string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrExists is returned when something exists when it may not be expected.
|
||||||
|
func ErrExists(msg string) error {
|
||||||
|
if msg == "" {
|
||||||
|
msg = "content: exists"
|
||||||
|
}
|
||||||
|
return contentExistsErr{
|
||||||
|
desc: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrNotFound is returned when an item is not found.
|
||||||
|
func ErrNotFound(msg string) error {
|
||||||
|
if msg == "" {
|
||||||
|
msg = "content: not found"
|
||||||
|
}
|
||||||
|
return contentNotFoundErr{
|
||||||
|
desc: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrLocked is returned when content is actively being uploaded, this
|
||||||
|
// indicates that another process is attempting to upload the same content.
|
||||||
|
func ErrLocked(msg string) error {
|
||||||
|
if msg == "" {
|
||||||
|
msg = "content: locked"
|
||||||
|
}
|
||||||
|
return contentLockedErr{
|
||||||
|
desc: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c contentExistsErr) Error() string {
|
||||||
|
return c.desc
|
||||||
|
}
|
||||||
|
func (c contentNotFoundErr) Error() string {
|
||||||
|
return c.desc
|
||||||
|
}
|
||||||
|
func (c contentLockedErr) Error() string {
|
||||||
|
return c.desc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c contentExistsErr) Exists() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c contentNotFoundErr) NotFound() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c contentLockedErr) Locked() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNotFound returns true if the error is due to a not found content item
|
||||||
|
func IsNotFound(err error) bool {
|
||||||
|
if err, ok := err.(interface {
|
||||||
|
NotFound() bool
|
||||||
|
}); ok {
|
||||||
|
return err.NotFound()
|
||||||
|
}
|
||||||
|
|
||||||
|
causal, ok := err.(interface {
|
||||||
|
Cause() error
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsNotFound(causal.Cause())
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsExists returns true if the error is due to an already existing content item
|
||||||
|
func IsExists(err error) bool {
|
||||||
|
if err, ok := err.(interface {
|
||||||
|
Exists() bool
|
||||||
|
}); ok {
|
||||||
|
return err.Exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
causal, ok := err.(interface {
|
||||||
|
Cause() error
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsExists(causal.Cause())
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLocked returns true if the error is due to a currently locked content item
|
||||||
|
func IsLocked(err error) bool {
|
||||||
|
if err, ok := err.(interface {
|
||||||
|
Locked() bool
|
||||||
|
}); ok {
|
||||||
|
return err.Locked()
|
||||||
|
}
|
||||||
|
|
||||||
|
causal, ok := err.(interface {
|
||||||
|
Cause() error
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsLocked(causal.Cause())
|
||||||
|
}
|
@ -1,9 +1,8 @@
|
|||||||
package content
|
package content
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handles locking references
|
// Handles locking references
|
||||||
@ -20,7 +19,7 @@ func tryLock(ref string) error {
|
|||||||
defer locksMu.Unlock()
|
defer locksMu.Unlock()
|
||||||
|
|
||||||
if _, ok := locks[ref]; ok {
|
if _, ok := locks[ref]; ok {
|
||||||
return errors.Wrapf(ErrLocked, "key %s is locked", ref)
|
return ErrLocked(fmt.Sprintf("key %s is locked", ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
locks[ref] = struct{}{}
|
locks[ref] = struct{}{}
|
||||||
|
@ -40,7 +40,7 @@ func (s *store) Info(ctx context.Context, dgst digest.Digest) (Info, error) {
|
|||||||
fi, err := os.Stat(p)
|
fi, err := os.Stat(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
err = ErrNotFound
|
err = ErrNotFound("")
|
||||||
}
|
}
|
||||||
|
|
||||||
return Info{}, err
|
return Info{}, err
|
||||||
@ -62,7 +62,7 @@ func (s *store) Reader(ctx context.Context, dgst digest.Digest) (io.ReadCloser,
|
|||||||
fp, err := os.Open(s.blobPath(dgst))
|
fp, err := os.Open(s.blobPath(dgst))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
err = ErrNotFound
|
err = ErrNotFound("")
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ func (cs *store) Delete(ctx context.Context, dgst digest.Digest) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrNotFound
|
return ErrNotFound("")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -323,7 +323,7 @@ func (s *store) Abort(ctx context.Context, ref string) error {
|
|||||||
root := s.ingestRoot(ref)
|
root := s.ingestRoot(ref)
|
||||||
if err := os.RemoveAll(root); err != nil {
|
if err := os.RemoveAll(root); err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return ErrNotFound
|
return ErrNotFound("")
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -99,7 +99,7 @@ func (w *writer) Commit(size int64, expected digest.Digest) error {
|
|||||||
if err := os.Rename(ingest, target); err != nil {
|
if err := os.Rename(ingest, target); err != nil {
|
||||||
if os.IsExist(err) {
|
if os.IsExist(err) {
|
||||||
// collision with the target file!
|
// collision with the target file!
|
||||||
return ErrExists
|
return ErrExists("")
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ func (s *containerStore) Get(ctx context.Context, id string) (containers.Contain
|
|||||||
|
|
||||||
bkt := getContainerBucket(s.tx, namespace, id)
|
bkt := getContainerBucket(s.tx, namespace, id)
|
||||||
if bkt == nil {
|
if bkt == nil {
|
||||||
return containers.Container{}, errors.Wrap(ErrNotFound, "bucket does not exist")
|
return containers.Container{}, ErrNotFound("bucket does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
container := containers.Container{ID: id}
|
container := containers.Container{ID: id}
|
||||||
@ -85,7 +85,7 @@ func (s *containerStore) Create(ctx context.Context, container containers.Contai
|
|||||||
cbkt, err := bkt.CreateBucket([]byte(container.ID))
|
cbkt, err := bkt.CreateBucket([]byte(container.ID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == bolt.ErrBucketExists {
|
if err == bolt.ErrBucketExists {
|
||||||
err = errors.Wrap(ErrExists, "content for id already exists")
|
err = ErrExists("content for id already exists")
|
||||||
}
|
}
|
||||||
return containers.Container{}, err
|
return containers.Container{}, err
|
||||||
}
|
}
|
||||||
@ -107,12 +107,12 @@ func (s *containerStore) Update(ctx context.Context, container containers.Contai
|
|||||||
|
|
||||||
bkt := getContainersBucket(s.tx, namespace)
|
bkt := getContainersBucket(s.tx, namespace)
|
||||||
if bkt == nil {
|
if bkt == nil {
|
||||||
return containers.Container{}, errors.Wrap(ErrNotFound, "no containers")
|
return containers.Container{}, ErrNotFound("no containers")
|
||||||
}
|
}
|
||||||
|
|
||||||
cbkt := bkt.Bucket([]byte(container.ID))
|
cbkt := bkt.Bucket([]byte(container.ID))
|
||||||
if cbkt == nil {
|
if cbkt == nil {
|
||||||
return containers.Container{}, errors.Wrap(ErrNotFound, "no content for id")
|
return containers.Container{}, ErrNotFound("no content for id")
|
||||||
}
|
}
|
||||||
|
|
||||||
container.UpdatedAt = time.Now()
|
container.UpdatedAt = time.Now()
|
||||||
@ -131,11 +131,11 @@ func (s *containerStore) Delete(ctx context.Context, id string) error {
|
|||||||
|
|
||||||
bkt := getContainersBucket(s.tx, namespace)
|
bkt := getContainersBucket(s.tx, namespace)
|
||||||
if bkt == nil {
|
if bkt == nil {
|
||||||
return errors.Wrap(ErrNotFound, "no containers")
|
return ErrNotFound("no containers")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bkt.DeleteBucket([]byte(id)); err == bolt.ErrBucketNotFound {
|
if err := bkt.DeleteBucket([]byte(id)); err == bolt.ErrBucketNotFound {
|
||||||
return errors.Wrap(ErrNotFound, "no content for id")
|
return ErrNotFound("no content for id")
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,117 @@
|
|||||||
package metadata
|
package metadata
|
||||||
|
|
||||||
import "github.com/pkg/errors"
|
type metadataExistsErr struct {
|
||||||
|
desc string
|
||||||
|
}
|
||||||
|
type metadataNotFoundErr struct {
|
||||||
|
desc string
|
||||||
|
}
|
||||||
|
type metadataNotEmptyErr struct {
|
||||||
|
desc string
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
// ErrExists is returned when an item already exists in metadata
|
||||||
ErrExists = errors.New("metadata: exists")
|
func ErrExists(msg string) error {
|
||||||
ErrNotFound = errors.New("metadata: not found")
|
if msg == "" {
|
||||||
ErrNotEmpty = errors.New("metadata: namespace not empty")
|
msg = "metadata: exists"
|
||||||
)
|
}
|
||||||
|
return metadataExistsErr{
|
||||||
|
desc: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IsNotFound returns true if the error is due to a missing image.
|
// ErrNotFound is returned when an item cannot be found in metadata
|
||||||
|
func ErrNotFound(msg string) error {
|
||||||
|
if msg == "" {
|
||||||
|
msg = "metadata: not found"
|
||||||
|
}
|
||||||
|
return metadataNotFoundErr{
|
||||||
|
desc: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrNotEmpty is returned when a metadata item can't be deleted because it is not empty
|
||||||
|
func ErrNotEmpty(msg string) error {
|
||||||
|
if msg == "" {
|
||||||
|
msg = "metadata: namespace not empty"
|
||||||
|
}
|
||||||
|
return metadataNotEmptyErr{
|
||||||
|
desc: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m metadataExistsErr) Error() string {
|
||||||
|
return m.desc
|
||||||
|
}
|
||||||
|
func (m metadataNotFoundErr) Error() string {
|
||||||
|
return m.desc
|
||||||
|
}
|
||||||
|
func (m metadataNotEmptyErr) Error() string {
|
||||||
|
return m.desc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m metadataExistsErr) Exists() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m metadataNotFoundErr) NotFound() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m metadataNotEmptyErr) NotEmpty() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsNotFound returns true if the error is due to a missing metadata item
|
||||||
func IsNotFound(err error) bool {
|
func IsNotFound(err error) bool {
|
||||||
return errors.Cause(err) == ErrNotFound
|
if err, ok := err.(interface {
|
||||||
|
NotFound() bool
|
||||||
|
}); ok {
|
||||||
|
return err.NotFound()
|
||||||
|
}
|
||||||
|
|
||||||
|
causal, ok := err.(interface {
|
||||||
|
Cause() error
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsNotFound(causal.Cause())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsExists returns true if the error is due to an already existing metadata item
|
||||||
func IsExists(err error) bool {
|
func IsExists(err error) bool {
|
||||||
return errors.Cause(err) == ErrExists
|
if err, ok := err.(interface {
|
||||||
|
Exists() bool
|
||||||
|
}); ok {
|
||||||
|
return err.Exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
causal, ok := err.(interface {
|
||||||
|
Cause() error
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsExists(causal.Cause())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsNotEmpty returns true if the error is due to delete request of a non-empty metadata item
|
||||||
func IsNotEmpty(err error) bool {
|
func IsNotEmpty(err error) bool {
|
||||||
return errors.Cause(err) == ErrNotEmpty
|
if err, ok := err.(interface {
|
||||||
|
NotEmpty() bool
|
||||||
|
}); ok {
|
||||||
|
return err.NotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
causal, ok := err.(interface {
|
||||||
|
Cause() error
|
||||||
|
})
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsNotEmpty(causal.Cause())
|
||||||
}
|
}
|
||||||
|
@ -30,12 +30,12 @@ func (s *imageStore) Get(ctx context.Context, name string) (images.Image, error)
|
|||||||
|
|
||||||
bkt := getImagesBucket(s.tx, namespace)
|
bkt := getImagesBucket(s.tx, namespace)
|
||||||
if bkt == nil {
|
if bkt == nil {
|
||||||
return images.Image{}, ErrNotFound
|
return images.Image{}, ErrNotFound("")
|
||||||
}
|
}
|
||||||
|
|
||||||
ibkt := bkt.Bucket([]byte(name))
|
ibkt := bkt.Bucket([]byte(name))
|
||||||
if ibkt == nil {
|
if ibkt == nil {
|
||||||
return images.Image{}, ErrNotFound
|
return images.Image{}, ErrNotFound("")
|
||||||
}
|
}
|
||||||
|
|
||||||
image.Name = name
|
image.Name = name
|
||||||
@ -124,7 +124,7 @@ func (s *imageStore) Delete(ctx context.Context, name string) error {
|
|||||||
return withImagesBucket(s.tx, namespace, func(bkt *bolt.Bucket) error {
|
return withImagesBucket(s.tx, namespace, func(bkt *bolt.Bucket) error {
|
||||||
err := bkt.DeleteBucket([]byte(name))
|
err := bkt.DeleteBucket([]byte(name))
|
||||||
if err == bolt.ErrBucketNotFound {
|
if err == bolt.ErrBucketNotFound {
|
||||||
return ErrNotFound
|
return ErrNotFound("")
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
@ -25,7 +25,7 @@ func (s *namespaceStore) Create(ctx context.Context, namespace string, labels ma
|
|||||||
bkt, err := topbkt.CreateBucket([]byte(namespace))
|
bkt, err := topbkt.CreateBucket([]byte(namespace))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == bolt.ErrBucketExists {
|
if err == bolt.ErrBucketExists {
|
||||||
return ErrExists
|
return ErrExists("")
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@ -100,12 +100,12 @@ func (s *namespaceStore) Delete(ctx context.Context, namespace string) error {
|
|||||||
if empty, err := s.namespaceEmpty(ctx, namespace); err != nil {
|
if empty, err := s.namespaceEmpty(ctx, namespace); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !empty {
|
} else if !empty {
|
||||||
return ErrNotEmpty
|
return ErrNotEmpty("")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := bkt.DeleteBucket([]byte(namespace)); err != nil {
|
if err := bkt.DeleteBucket([]byte(namespace)); err != nil {
|
||||||
if err == bolt.ErrBucketNotFound {
|
if err == bolt.ErrBucketNotFound {
|
||||||
return ErrNotFound
|
return ErrNotFound("")
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -31,7 +31,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
|
|||||||
status, err := p.tracker.GetStatus(ref)
|
status, err := p.tracker.GetStatus(ref)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if status.Offset == status.Total {
|
if status.Offset == status.Total {
|
||||||
return nil, content.ErrExists
|
return nil, content.ErrExists("")
|
||||||
}
|
}
|
||||||
// TODO: Handle incomplete status
|
// TODO: Handle incomplete status
|
||||||
} else if !content.IsNotFound(err) {
|
} else if !content.IsNotFound(err) {
|
||||||
@ -72,7 +72,7 @@ func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor) (conten
|
|||||||
// TODO: Set updated time?
|
// TODO: Set updated time?
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return nil, content.ErrExists
|
return nil, content.ErrExists("")
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusNotFound {
|
if resp.StatusCode != http.StatusNotFound {
|
||||||
// TODO: log error
|
// TODO: log error
|
||||||
|
@ -34,7 +34,7 @@ func (t *memoryStatusTracker) GetStatus(ref string) (Status, error) {
|
|||||||
defer t.m.Unlock()
|
defer t.m.Unlock()
|
||||||
status, ok := t.statuses[ref]
|
status, ok := t.statuses[ref]
|
||||||
if !ok {
|
if !ok {
|
||||||
return Status{}, content.ErrNotFound
|
return Status{}, content.ErrNotFound("")
|
||||||
}
|
}
|
||||||
return status, nil
|
return status, nil
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,12 @@ import (
|
|||||||
func rewriteGRPCError(err error) error {
|
func rewriteGRPCError(err error) error {
|
||||||
switch grpc.Code(errors.Cause(err)) {
|
switch grpc.Code(errors.Cause(err)) {
|
||||||
case codes.AlreadyExists:
|
case codes.AlreadyExists:
|
||||||
return content.ErrExists
|
return content.ErrExists(grpc.ErrorDesc(err))
|
||||||
case codes.NotFound:
|
case codes.NotFound:
|
||||||
return content.ErrNotFound
|
return content.ErrNotFound(grpc.ErrorDesc(err))
|
||||||
case codes.Unavailable:
|
case codes.Unavailable:
|
||||||
return content.ErrLocked
|
return content.ErrLocked(grpc.ErrorDesc(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +69,9 @@ func rewriteGRPCError(err error) error {
|
|||||||
|
|
||||||
switch grpc.Code(errors.Cause(err)) {
|
switch grpc.Code(errors.Cause(err)) {
|
||||||
case codes.AlreadyExists:
|
case codes.AlreadyExists:
|
||||||
return metadata.ErrExists
|
return metadata.ErrExists(grpc.ErrorDesc(err))
|
||||||
case codes.NotFound:
|
case codes.NotFound:
|
||||||
return metadata.ErrNotFound
|
return metadata.ErrNotFound(grpc.ErrorDesc(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -27,9 +27,9 @@ func rewriteGRPCError(err error) error {
|
|||||||
|
|
||||||
switch grpc.Code(errors.Cause(err)) {
|
switch grpc.Code(errors.Cause(err)) {
|
||||||
case codes.AlreadyExists:
|
case codes.AlreadyExists:
|
||||||
return metadata.ErrExists
|
return metadata.ErrExists(grpc.ErrorDesc(err))
|
||||||
case codes.NotFound:
|
case codes.NotFound:
|
||||||
return metadata.ErrNotFound
|
return metadata.ErrNotFound(grpc.ErrorDesc(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user