Refactor host_repo -> domain errors (#786)
* Refactor domain errors: New -> E, create helper New and Wrap * Update host repo to use domain errors
This commit is contained in:
1 parent
aa4157639c
commit
ec0020de90
33 files changed
+996
-374
No files matched your search
@@ -145,9 +145,10 @@ func backendErrorToApiError(inErr error) error {
|
||||
Kind: codes.Unimplemented.String(),
|
||||
Message: stErr.Message(),
|
||||
}}
|
||||
case errors.Is(inErr, errors.ErrRecordNotFound):
|
||||
case errors.Is(inErr, errors.ErrRecordNotFound), errors.Match(errors.T(errors.RecordNotFound), inErr):
|
||||
return NotFoundErrorf(genericNotFoundMsg)
|
||||
case errors.Is(inErr, errors.ErrInvalidFieldMask), errors.Is(inErr, errors.ErrEmptyFieldMask):
|
||||
case errors.Is(inErr, errors.ErrInvalidFieldMask), errors.Is(inErr, errors.ErrEmptyFieldMask),
|
||||
errors.Match(errors.T(errors.InvalidFieldMask), inErr), errors.Match(errors.T(errors.EmptyFieldMask), inErr):
|
||||
return InvalidArgumentErrorf("Error in provided request", map[string]string{"update_mask": "Invalid update mask provided."})
|
||||
case errors.IsUniqueError(inErr), errors.Is(inErr, errors.ErrNotUnique):
|
||||
return InvalidArgumentErrorf(genericUniquenessMsg, nil)
|
||||
|
||||
@@ -100,7 +100,7 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Kind: "Internal",
|
||||
Message: "Some random error",
|
||||
},
|
||||
},
|
||||
@@ -111,22 +111,44 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Kind: "Internal",
|
||||
Message: fmt.Sprintf("test error: %s", errors.ErrInvalidPublicId),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db invalid parameter",
|
||||
err: errors.E(errors.WithCode(errors.InvalidPublicId)),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Message: "invalid public id, parameter violation: error #102",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db invalid parameter",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrInvalidParameter),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Kind: "Internal",
|
||||
Message: fmt.Sprintf("test error: %s", errors.ErrInvalidParameter),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db invalid parameter",
|
||||
err: errors.E(errors.WithCode(errors.InvalidParameter)),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Message: "invalid parameter, parameter violation: error #100",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db invalid field mask",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrInvalidFieldMask),
|
||||
@@ -139,6 +161,18 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db invalid field mask",
|
||||
err: errors.E(errors.WithCode(errors.InvalidFieldMask)),
|
||||
expected: apiError{
|
||||
status: http.StatusBadRequest,
|
||||
inner: &pb.Error{
|
||||
Kind: "InvalidArgument",
|
||||
Message: "Error in provided request",
|
||||
Details: &pb.ErrorDetails{RequestFields: []*pb.FieldError{{Name: "update_mask", Description: "Invalid update mask provided."}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db empty field mask",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrEmptyFieldMask),
|
||||
@@ -151,6 +185,18 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db empty field mask",
|
||||
err: errors.E(errors.WithCode(errors.EmptyFieldMask)),
|
||||
expected: apiError{
|
||||
status: http.StatusBadRequest,
|
||||
inner: &pb.Error{
|
||||
Kind: "InvalidArgument",
|
||||
Message: "Error in provided request",
|
||||
Details: &pb.ErrorDetails{RequestFields: []*pb.FieldError{{Name: "update_mask", Description: "Invalid update mask provided."}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db not unique",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrNotUnique),
|
||||
@@ -162,6 +208,17 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db not unqiue",
|
||||
err: errors.E(errors.WithCode(errors.NotUnique)),
|
||||
expected: apiError{
|
||||
status: http.StatusBadRequest,
|
||||
inner: &pb.Error{
|
||||
Kind: "InvalidArgument",
|
||||
Message: genericUniquenessMsg,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db record not found",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrRecordNotFound),
|
||||
@@ -173,17 +230,50 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db record not found",
|
||||
err: errors.E(errors.WithCode(errors.RecordNotFound)),
|
||||
expected: apiError{
|
||||
status: http.StatusNotFound,
|
||||
inner: &pb.Error{
|
||||
Kind: "NotFound",
|
||||
Message: genericNotFoundMsg,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db multiple records",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrMultipleRecords),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Kind: "Internal",
|
||||
Message: fmt.Sprintf("test error: %s", errors.ErrMultipleRecords),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db multiple records",
|
||||
err: errors.E(errors.WithCode(errors.MultipleRecords)),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Message: "multiple records, search issue: error #1101",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Wrapped domain error",
|
||||
err: errors.E(errors.WithCode(errors.InvalidAddress), errors.WithMsg("test msg"), errors.WithWrap(errors.E(errors.WithCode(errors.NotNull), errors.WithMsg("inner msg")))),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Message: "test msg: parameter violation: error #101: inner msg: integrity violation: error #1001",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/auth"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/hostcatalogs"
|
||||
pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services"
|
||||
"github.com/hashicorp/boundary/internal/host"
|
||||
@@ -180,6 +181,10 @@ func (s Service) createInRepo(ctx context.Context, projId string, item *pb.HostC
|
||||
}
|
||||
h, err := static.NewHostCatalog(projId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host catalog for creation: %v.", err)
|
||||
}
|
||||
repo, err := s.staticRepoFn()
|
||||
@@ -188,6 +193,10 @@ func (s Service) createInRepo(ctx context.Context, projId string, item *pb.HostC
|
||||
}
|
||||
out, err := repo.CreateCatalog(ctx, h)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to create host catalog: %w", err)
|
||||
}
|
||||
if out == nil {
|
||||
@@ -207,6 +216,10 @@ func (s Service) updateInRepo(ctx context.Context, projId, id string, mask []str
|
||||
version := item.GetVersion()
|
||||
h, err := static.NewHostCatalog(projId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to build host catalog for update: %w", err)
|
||||
}
|
||||
h.PublicId = id
|
||||
@@ -220,6 +233,10 @@ func (s Service) updateInRepo(ctx context.Context, projId, id string, mask []str
|
||||
}
|
||||
out, rowsUpdated, err := repo.UpdateCatalog(ctx, h, version, dbMask)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to update host catalog: %w", err)
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
@@ -235,6 +252,10 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
|
||||
}
|
||||
rows, err := repo.DeleteCatalog(ctx, id)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return false, e
|
||||
}
|
||||
return false, fmt.Errorf("unable to delete host: %w", err)
|
||||
}
|
||||
return rows > 0, nil
|
||||
|
||||
@@ -212,6 +212,10 @@ func (s Service) createInRepo(ctx context.Context, scopeId, catalogId string, it
|
||||
}
|
||||
h, err := static.NewHostSet(catalogId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host set for creation: %v.", err)
|
||||
}
|
||||
repo, err := s.staticRepoFn()
|
||||
@@ -220,9 +224,9 @@ func (s Service) createInRepo(ctx context.Context, scopeId, catalogId string, it
|
||||
}
|
||||
out, err := repo.CreateSet(ctx, scopeId, h)
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) || errors.Is(err, errors.ErrNotUnique) {
|
||||
// Push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, err
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to create host set: %w", err)
|
||||
}
|
||||
@@ -242,6 +246,10 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, catalogId, id string
|
||||
}
|
||||
h, err := static.NewHostSet(catalogId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host set for update: %v.", err)
|
||||
}
|
||||
h.PublicId = id
|
||||
@@ -255,6 +263,10 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, catalogId, id string
|
||||
}
|
||||
out, m, rowsUpdated, err := repo.UpdateSet(ctx, scopeId, h, item.GetVersion(), dbMask)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to update host set: %w.", err)
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
@@ -270,6 +282,10 @@ func (s Service) deleteFromRepo(ctx context.Context, scopeId, id string) (bool,
|
||||
}
|
||||
rows, err := repo.DeleteSet(ctx, scopeId, id)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return false, e
|
||||
}
|
||||
return false, fmt.Errorf("unable to delete host: %w", err)
|
||||
}
|
||||
return rows > 0, nil
|
||||
@@ -298,11 +314,18 @@ func (s Service) addInRepo(ctx context.Context, scopeId, setId string, hostIds [
|
||||
}
|
||||
_, err = repo.AddSetMembers(ctx, scopeId, setId, version, strutil.RemoveDuplicates(hostIds, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to add hosts to host set: %v.", err)
|
||||
}
|
||||
out, m, err := repo.LookupSet(ctx, setId)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to look up host set after adding hosts: %w", err)
|
||||
}
|
||||
if out == nil {
|
||||
@@ -318,12 +341,19 @@ func (s Service) setInRepo(ctx context.Context, scopeId, setId string, hostIds [
|
||||
}
|
||||
_, _, err = repo.SetSetMembers(ctx, scopeId, setId, version, strutil.RemoveDuplicates(hostIds, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to set hosts in host set: %v.", err)
|
||||
}
|
||||
|
||||
out, m, err := repo.LookupSet(ctx, setId)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to look up host set after setting hosts: %w", err)
|
||||
}
|
||||
if out == nil {
|
||||
@@ -339,11 +369,18 @@ func (s Service) removeInRepo(ctx context.Context, scopeId, setId string, hostId
|
||||
}
|
||||
_, err = repo.DeleteSetMembers(ctx, scopeId, setId, version, strutil.RemoveDuplicates(hostIds, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to remove hosts from host set: %v.", err)
|
||||
}
|
||||
out, m, err := repo.LookupSet(ctx, setId)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to look up host set: %w", err)
|
||||
}
|
||||
if out == nil {
|
||||
|
||||
@@ -169,6 +169,10 @@ func (s Service) createInRepo(ctx context.Context, scopeId, catalogId string, it
|
||||
}
|
||||
h, err := static.NewHost(catalogId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host for creation: %v.", err)
|
||||
}
|
||||
|
||||
@@ -178,9 +182,9 @@ func (s Service) createInRepo(ctx context.Context, scopeId, catalogId string, it
|
||||
}
|
||||
out, err := repo.CreateHost(ctx, scopeId, h)
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) || errors.Is(err, errors.ErrNotUnique) {
|
||||
// Push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, err
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create host: %v.", err)
|
||||
}
|
||||
@@ -207,6 +211,10 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, catalogId, id string
|
||||
}
|
||||
h, err := static.NewHost(catalogId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host for update: %v.", err)
|
||||
}
|
||||
h.PublicId = id
|
||||
@@ -220,6 +228,10 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, catalogId, id string
|
||||
}
|
||||
out, rowsUpdated, err := repo.UpdateHost(ctx, scopeId, h, item.GetVersion(), dbMask)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to update host: %w", err)
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
@@ -235,6 +247,10 @@ func (s Service) deleteFromRepo(ctx context.Context, scopeId, id string) (bool,
|
||||
}
|
||||
rows, err := repo.DeleteHost(ctx, scopeId, id)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return false, e
|
||||
}
|
||||
return false, fmt.Errorf("unable to delete host: %w", err)
|
||||
}
|
||||
return rows > 0, nil
|
||||
|
||||
Reference in new issue
Block a user