Skip to content

Commit 83a061b

Browse files
committed
ING-865: Update error information to include extra context
1 parent 2e7ec97 commit 83a061b

File tree

3 files changed

+86
-53
lines changed

3 files changed

+86
-53
lines changed

gateway/dataimpl/server_v1/errorhandler.go

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,19 @@ func (e ErrorHandler) NewDocConflictStatus(ctx context.Context, baseErr error, b
625625
return st
626626
}
627627

628-
func (e ErrorHandler) NewZeroCasStatus(ctx context.Context) *status.Status {
629-
st := e.newStatus(ctx, codes.InvalidArgument, "CAS value cannot be zero.")
628+
func (e ErrorHandler) NewZeroCasStatus(ctx context.Context, casField string) *status.Status {
629+
var st *status.Status
630+
if casField == "" {
631+
st = e.newStatus(ctx, codes.InvalidArgument, "CAS value cannot be zero.")
632+
} else {
633+
st = e.newStatus(ctx, codes.InvalidArgument, fmt.Sprintf("CAS value for '%s' cannot be zero.", casField))
634+
}
635+
st = e.tryAttachStatusDetails(st, &epb.ErrorInfo{
636+
Metadata: map[string]string{
637+
"casField": casField,
638+
},
639+
})
640+
630641
return st
631642
}
632643

@@ -805,10 +816,10 @@ func (e ErrorHandler) NewSdDocNotJsonStatus(ctx context.Context, baseErr error,
805816
return st
806817
}
807818

808-
func (e ErrorHandler) NewSdPathNotFoundStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string) *status.Status {
819+
func (e ErrorHandler) NewSdPathNotFoundStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string, sdIndex int) *status.Status {
809820
st := e.newStatus(ctx, codes.NotFound,
810-
fmt.Sprintf("Subdocument path '%s' was not found in '%s' in '%s/%s/%s'.",
811-
sdPath, docId, bucketName, scopeName, collectionName))
821+
fmt.Sprintf("Subdocument path '%s' at index %d was not found in '%s' in '%s/%s/%s'.",
822+
sdPath, sdIndex, docId, bucketName, scopeName, collectionName))
812823
st = e.tryAttachStatusDetails(st, &epb.ResourceInfo{
813824
ResourceType: "path",
814825
ResourceName: fmt.Sprintf("%s/%s/%s/%s/%s", bucketName, scopeName, collectionName, docId, sdPath),
@@ -818,10 +829,10 @@ func (e ErrorHandler) NewSdPathNotFoundStatus(ctx context.Context, baseErr error
818829
return st
819830
}
820831

821-
func (e ErrorHandler) NewSdPathExistsStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string) *status.Status {
832+
func (e ErrorHandler) NewSdPathExistsStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string, sdIndex int) *status.Status {
822833
st := e.newStatus(ctx, codes.AlreadyExists,
823-
fmt.Sprintf("Subdocument path '%s' already existed in '%s' in '%s/%s/%s'.",
824-
sdPath, docId, bucketName, scopeName, collectionName))
834+
fmt.Sprintf("Subdocument path '%s' at index %d already existed in '%s' in '%s/%s/%s'.",
835+
sdPath, sdIndex, docId, bucketName, scopeName, collectionName))
825836
st = e.tryAttachStatusDetails(st, &epb.ResourceInfo{
826837
ResourceType: "path",
827838
ResourceName: fmt.Sprintf("%s/%s/%s/%s/%s", bucketName, scopeName, collectionName, docId, sdPath),
@@ -831,10 +842,10 @@ func (e ErrorHandler) NewSdPathExistsStatus(ctx context.Context, baseErr error,
831842
return st
832843
}
833844

834-
func (e ErrorHandler) NewSdPathMismatchStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string) *status.Status {
845+
func (e ErrorHandler) NewSdPathMismatchStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string, sdIndex int) *status.Status {
835846
st := e.newStatus(ctx, codes.FailedPrecondition,
836-
fmt.Sprintf("Document structure implied by path '%s' did not match document '%s' in '%s/%s/%s'.",
837-
sdPath, docId, bucketName, scopeName, collectionName))
847+
fmt.Sprintf("Document structure implied by path '%s' at index %d did not match document '%s' in '%s/%s/%s'.",
848+
sdPath, sdIndex, docId, bucketName, scopeName, collectionName))
838849
st = e.tryAttachStatusDetails(st, &epb.PreconditionFailure{
839850
Violations: []*epb.PreconditionFailure_Violation{{
840851
Type: "PATH_MISMATCH",
@@ -846,25 +857,25 @@ func (e ErrorHandler) NewSdPathMismatchStatus(ctx context.Context, baseErr error
846857
return st
847858
}
848859

849-
func (e ErrorHandler) NewSdPathTooBigStatus(ctx context.Context, baseErr error, sdPath string) *status.Status {
860+
func (e ErrorHandler) NewSdPathTooBigStatus(ctx context.Context, baseErr error, sdPath string, sdIndex int) *status.Status {
850861
st := e.newStatus(ctx, codes.InvalidArgument,
851-
fmt.Sprintf("Subdocument path '%s' is too long", sdPath))
862+
fmt.Sprintf("Subdocument path '%s' at index %d is too long", sdPath, sdIndex))
852863
st = e.tryAttachExtraContext(st, baseErr)
853864
return st
854865
}
855866

856-
func (e ErrorHandler) NewSdBadValueStatus(ctx context.Context, baseErr error, sdPath string) *status.Status {
867+
func (e ErrorHandler) NewSdBadValueStatus(ctx context.Context, baseErr error, sdPath string, sdIndex int) *status.Status {
857868
st := e.newStatus(ctx, codes.InvalidArgument,
858-
fmt.Sprintf("Subdocument operation content for path '%s' would invalidate the JSON if added to the document.",
859-
sdPath))
869+
fmt.Sprintf("Subdocument operation content for path '%s' at index %d would invalidate the JSON if added to the document.",
870+
sdPath, sdIndex))
860871
st = e.tryAttachExtraContext(st, baseErr)
861872
return st
862873
}
863874

864-
func (e ErrorHandler) NewSdValueOutOfRangeStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string) *status.Status {
875+
func (e ErrorHandler) NewSdValueOutOfRangeStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string, sdIndex int) *status.Status {
865876
st := e.newStatus(ctx, codes.FailedPrecondition,
866-
fmt.Sprintf("Counter operation content for path '%s' would put the JSON value out of range.",
867-
sdPath))
877+
fmt.Sprintf("Counter operation content for path '%s' at index %d would put the JSON value out of range.",
878+
sdPath, sdIndex))
868879
st = e.tryAttachStatusDetails(st, &epb.PreconditionFailure{
869880
Violations: []*epb.PreconditionFailure_Violation{{
870881
Type: "VALUE_OUT_OF_RANGE",
@@ -876,10 +887,10 @@ func (e ErrorHandler) NewSdValueOutOfRangeStatus(ctx context.Context, baseErr er
876887
return st
877888
}
878889

879-
func (e ErrorHandler) NewSdBadRangeStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string) *status.Status {
890+
func (e ErrorHandler) NewSdBadRangeStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string, sdIndex int) *status.Status {
880891
st := e.newStatus(ctx, codes.FailedPrecondition,
881-
fmt.Sprintf("The value at path '%s' is out of the valid range in document '%s' in '%s/%s/%s'.",
882-
sdPath, docId, bucketName, scopeName, collectionName))
892+
fmt.Sprintf("The value at path '%s' at index %d is out of the valid range in document '%s' in '%s/%s/%s'.",
893+
sdPath, sdIndex, docId, bucketName, scopeName, collectionName))
883894
st = e.tryAttachStatusDetails(st, &epb.PreconditionFailure{
884895
Violations: []*epb.PreconditionFailure_Violation{{
885896
Type: "PATH_VALUE_OUT_OF_RANGE",
@@ -891,25 +902,25 @@ func (e ErrorHandler) NewSdBadRangeStatus(ctx context.Context, baseErr error, bu
891902
return st
892903
}
893904

894-
func (e ErrorHandler) NewSdBadDeltaStatus(ctx context.Context, baseErr error, sdPath string) *status.Status {
905+
func (e ErrorHandler) NewSdBadDeltaStatus(ctx context.Context, baseErr error, sdPath string, sdIndex int) *status.Status {
895906
st := e.newStatus(ctx, codes.InvalidArgument,
896-
fmt.Sprintf("Subdocument counter delta for path '%s' was invalid. Delta must be a non-zero number within the range of an 64-bit signed integer.",
897-
sdPath))
907+
fmt.Sprintf("Subdocument counter delta for path '%s' at index %d was invalid. Delta must be a non-zero number within the range of an 64-bit signed integer.",
908+
sdPath, sdIndex))
898909
st = e.tryAttachExtraContext(st, baseErr)
899910
return st
900911
}
901912

902-
func (e ErrorHandler) NewSdValueTooDeepStatus(ctx context.Context, baseErr error, sdPath string) *status.Status {
913+
func (e ErrorHandler) NewSdValueTooDeepStatus(ctx context.Context, baseErr error, sdPath string, sdIndex int) *status.Status {
903914
st := e.newStatus(ctx, codes.InvalidArgument,
904-
fmt.Sprintf("Subdocument operation content for path '%s' was too deep to parse.",
905-
sdPath))
915+
fmt.Sprintf("Subdocument operation content for path '%s' at index %d was too deep to parse.",
916+
sdPath, sdIndex))
906917
st = e.tryAttachExtraContext(st, baseErr)
907918
return st
908919
}
909920

910-
func (e ErrorHandler) NewSdXattrUnknownVattrStatus(ctx context.Context, baseErr error, sdPath string) *status.Status {
921+
func (e ErrorHandler) NewSdXattrUnknownVattrStatus(ctx context.Context, baseErr error, sdPath string, sdIndex int) *status.Status {
911922
st := e.newStatus(ctx, codes.InvalidArgument,
912-
fmt.Sprintf("Subdocument path '%s' references an invalid virtual attribute.", sdPath))
923+
fmt.Sprintf("Subdocument path '%s' at index %d references an invalid virtual attribute.", sdPath, sdIndex))
913924
st = e.tryAttachExtraContext(st, baseErr)
914925
return st
915926
}
@@ -920,13 +931,35 @@ func (e ErrorHandler) NewSdBadCombo(ctx context.Context, baseErr error) *status.
920931
return st
921932
}
922933

923-
func (e ErrorHandler) NewSdPathInvalidStatus(ctx context.Context, baseErr error, sdPath string) *status.Status {
934+
func (e ErrorHandler) NewSdPathInvalidStatus(ctx context.Context, baseErr error, sdPath string, sdIndex int) *status.Status {
935+
st := e.newStatus(ctx, codes.InvalidArgument,
936+
fmt.Sprintf("Invalid subdocument path syntax '%s' at index %d.", sdPath, sdIndex))
937+
st = e.tryAttachExtraContext(st, baseErr)
938+
return st
939+
}
940+
941+
func (e ErrorHandler) NewProjectPathInvalidStatus(ctx context.Context, baseErr error, sdPath string) *status.Status {
924942
st := e.newStatus(ctx, codes.InvalidArgument,
925943
fmt.Sprintf("Invalid subdocument path syntax '%s'.", sdPath))
926944
st = e.tryAttachExtraContext(st, baseErr)
927945
return st
928946
}
929947

948+
func (e ErrorHandler) NewProjectPathMismatchStatus(ctx context.Context, baseErr error, bucketName, scopeName, collectionName, docId, sdPath string) *status.Status {
949+
st := e.newStatus(ctx, codes.FailedPrecondition,
950+
fmt.Sprintf("Document structure implied by path '%s' did not match document '%s' in '%s/%s/%s'.",
951+
sdPath, docId, bucketName, scopeName, collectionName))
952+
st = e.tryAttachStatusDetails(st, &epb.PreconditionFailure{
953+
Violations: []*epb.PreconditionFailure_Violation{{
954+
Type: "PATH_MISMATCH",
955+
Subject: fmt.Sprintf("document/%s/%s/%s/%s/%s", bucketName, scopeName, collectionName, docId, sdPath),
956+
Description: "",
957+
}},
958+
})
959+
st = e.tryAttachExtraContext(st, baseErr)
960+
return st
961+
}
962+
930963
func (e ErrorHandler) NewInvalidSnappyValueError(ctx context.Context) *status.Status {
931964
st := e.newStatus(ctx, codes.InvalidArgument, "Failed to snappy inflate value.")
932965
return st

gateway/dataimpl/server_v1/kvserver.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ func (s *KvServer) Get(ctx context.Context, in *kv_v1.GetRequest) (*kv_v1.GetRes
7474
} else if errors.Is(err, memdx.ErrSubDocNotJSON) {
7575
return nil, s.errorHandler.NewSdDocNotJsonStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key).Err()
7676
} else if errors.Is(err, memdx.ErrSubDocPathInvalid) {
77-
return nil, s.errorHandler.NewSdPathInvalidStatus(ctx, err, path).Err()
77+
return nil, s.errorHandler.NewProjectPathInvalidStatus(ctx, err, path).Err()
7878
} else if errors.Is(err, memdx.ErrSubDocPathMismatch) {
79-
return nil, s.errorHandler.NewSdPathMismatchStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, path).Err()
79+
return nil, s.errorHandler.NewProjectPathMismatchStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, path).Err()
8080
}
8181

8282
return nil, s.errorHandler.NewGenericStatus(ctx, err).Err()
@@ -1078,15 +1078,15 @@ func (s *KvServer) LookupIn(ctx context.Context, in *kv_v1.LookupInRequest) (*kv
10781078
} else if errors.Is(op.Err, memdx.ErrSubDocNotJSON) {
10791079
spec.Status = s.errorHandler.NewSdDocNotJsonStatus(ctx, op.Err, in.BucketName, in.ScopeName, in.CollectionName, in.Key).Proto()
10801080
} else if errors.Is(op.Err, memdx.ErrSubDocPathNotFound) {
1081-
spec.Status = s.errorHandler.NewSdPathNotFoundStatus(ctx, op.Err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[i].Path).Proto()
1081+
spec.Status = s.errorHandler.NewSdPathNotFoundStatus(ctx, op.Err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[i].Path, i).Proto()
10821082
} else if errors.Is(op.Err, memdx.ErrSubDocPathInvalid) {
1083-
spec.Status = s.errorHandler.NewSdPathInvalidStatus(ctx, op.Err, in.Specs[i].Path).Proto()
1083+
spec.Status = s.errorHandler.NewSdPathInvalidStatus(ctx, op.Err, in.Specs[i].Path, i).Proto()
10841084
} else if errors.Is(op.Err, memdx.ErrSubDocPathMismatch) {
1085-
spec.Status = s.errorHandler.NewSdPathMismatchStatus(ctx, op.Err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[i].Path).Proto()
1085+
spec.Status = s.errorHandler.NewSdPathMismatchStatus(ctx, op.Err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[i].Path, i).Proto()
10861086
} else if errors.Is(op.Err, memdx.ErrSubDocPathTooBig) {
1087-
spec.Status = s.errorHandler.NewSdPathTooBigStatus(ctx, op.Err, in.Specs[i].Path).Proto()
1087+
spec.Status = s.errorHandler.NewSdPathTooBigStatus(ctx, op.Err, in.Specs[i].Path, i).Proto()
10881088
} else if errors.Is(op.Err, memdx.ErrSubDocXattrUnknownVAttr) {
1089-
spec.Status = s.errorHandler.NewSdXattrUnknownVattrStatus(ctx, op.Err, in.Specs[i].Path).Proto()
1089+
spec.Status = s.errorHandler.NewSdXattrUnknownVattrStatus(ctx, op.Err, in.Specs[i].Path, i).Proto()
10901090
} else {
10911091
spec.Status = s.errorHandler.NewGenericStatus(ctx, op.Err).Proto()
10921092
}
@@ -1291,28 +1291,28 @@ func (s *KvServer) MutateIn(ctx context.Context, in *kv_v1.MutateInRequest) (*kv
12911291
} else if errors.Is(err, memdx.ErrSubDocNotJSON) {
12921292
return nil, s.errorHandler.NewSdDocNotJsonStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key).Err()
12931293
} else if errors.Is(err, memdx.ErrSubDocPathNotFound) {
1294-
return nil, s.errorHandler.NewSdPathNotFoundStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path).Err()
1294+
return nil, s.errorHandler.NewSdPathNotFoundStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
12951295
} else if errors.Is(err, memdx.ErrSubDocPathExists) {
1296-
return nil, s.errorHandler.NewSdPathExistsStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path).Err()
1296+
return nil, s.errorHandler.NewSdPathExistsStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
12971297
} else if errors.Is(err, memdx.ErrSubDocPathInvalid) {
1298-
return nil, s.errorHandler.NewSdPathInvalidStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path).Err()
1298+
return nil, s.errorHandler.NewSdPathInvalidStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
12991299
} else if errors.Is(err, memdx.ErrSubDocPathMismatch) {
1300-
return nil, s.errorHandler.NewSdPathMismatchStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path).Err()
1300+
return nil, s.errorHandler.NewSdPathMismatchStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
13011301
} else if errors.Is(err, memdx.ErrSubDocPathTooBig) {
1302-
return nil, s.errorHandler.NewSdPathTooBigStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path).Err()
1302+
return nil, s.errorHandler.NewSdPathTooBigStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
13031303
} else if errors.Is(err, memdx.ErrSubDocCantInsert) {
13041304
opSpec := in.Specs[subdocErr.OpIndex]
13051305
if opSpec.Operation == kv_v1.MutateInRequest_Spec_OPERATION_COUNTER {
1306-
return nil, s.errorHandler.NewSdValueOutOfRangeStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path).Err()
1306+
return nil, s.errorHandler.NewSdValueOutOfRangeStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
13071307
} else {
1308-
return nil, s.errorHandler.NewSdBadValueStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path).Err()
1308+
return nil, s.errorHandler.NewSdBadValueStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
13091309
}
13101310
} else if errors.Is(err, memdx.ErrSubDocBadRange) {
1311-
return nil, s.errorHandler.NewSdBadRangeStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path).Err()
1311+
return nil, s.errorHandler.NewSdBadRangeStatus(ctx, err, in.BucketName, in.ScopeName, in.CollectionName, in.Key, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
13121312
} else if errors.Is(err, memdx.ErrSubDocBadDelta) {
1313-
return nil, s.errorHandler.NewSdBadDeltaStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path).Err()
1313+
return nil, s.errorHandler.NewSdBadDeltaStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
13141314
} else if errors.Is(err, memdx.ErrSubDocValueTooDeep) {
1315-
return nil, s.errorHandler.NewSdValueTooDeepStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path).Err()
1315+
return nil, s.errorHandler.NewSdValueTooDeepStatus(ctx, err, in.Specs[subdocErr.OpIndex].Path, subdocErr.OpIndex).Err()
13161316
}
13171317
}
13181318
}
@@ -1412,7 +1412,7 @@ func (s *KvServer) checkKey(ctx context.Context, key string) *status.Status {
14121412

14131413
func (s *KvServer) checkCAS(ctx context.Context, cas *uint64) *status.Status {
14141414
if cas != nil && *cas == 0 {
1415-
return s.errorHandler.NewZeroCasStatus(ctx)
1415+
return s.errorHandler.NewZeroCasStatus(ctx, "")
14161416
}
14171417

14181418
return nil

gateway/dataimpl/server_v1/xdcrserver.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ func (s *XdcrServer) PushDocument(
618618
return nil, errSt.Err()
619619
}
620620

621-
errSt = s.checkCAS(ctx, &in.StoreCas)
621+
errSt = s.checkCAS(ctx, &in.StoreCas, "StoreCas")
622622
if errSt != nil {
623623
return nil, errSt.Err()
624624
}
@@ -679,7 +679,7 @@ func (s *XdcrServer) PushDocument(
679679
var checkCas uint64
680680
if in.CheckCas != nil {
681681
if *in.CheckCas == 0 {
682-
return nil, s.errorHandler.NewZeroCasStatus(ctx).Err()
682+
return nil, s.errorHandler.NewZeroCasStatus(ctx, "CheckCas").Err()
683683
}
684684
checkCas = *in.CheckCas
685685
} else {
@@ -863,9 +863,9 @@ func (s *XdcrServer) checkKey(ctx context.Context, key string) *status.Status {
863863
return nil
864864
}
865865

866-
func (s *XdcrServer) checkCAS(ctx context.Context, cas *uint64) *status.Status {
866+
func (s *XdcrServer) checkCAS(ctx context.Context, cas *uint64, casField string) *status.Status {
867867
if cas != nil && *cas == 0 {
868-
return s.errorHandler.NewZeroCasStatus(ctx)
868+
return s.errorHandler.NewZeroCasStatus(ctx, casField)
869869
}
870870

871871
return nil

0 commit comments

Comments
 (0)