field NotFound err in kopia, handle in cli (#1027)

## Description

Replace the `manifest.NotFound` error production
in kopia wrapper with a local version of the error. This allows the cli to catch the corso error and
write a clearer response to the end user.

## Type of change

- [x] 🌻 Feature

## Issue(s)

* #976 

## Test Plan

- [x] 💪 Manual
- [x] 💚 E2E
This commit is contained in:
Keepers 2022-10-04 12:27:23 -06:00 committed by GitHub
parent d0560500d2
commit 67215c9bf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 19 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/alcionai/corso/src/cli/options"
. "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/kopia"
"github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/pkg/backup"
"github.com/alcionai/corso/src/pkg/backup/details"
@ -422,6 +423,10 @@ func runDetailsExchangeCmd(
) (*details.Details, error) {
d, _, err := r.BackupDetails(ctx, backupID)
if err != nil {
if errors.Is(err, kopia.ErrNotFound) {
return nil, errors.Errorf("no backup exists with the id %s", backupID)
}
return nil, errors.Wrap(err, "Failed to get backup details in the repository")
}

View File

@ -11,6 +11,7 @@ import (
"github.com/alcionai/corso/src/cli/options"
. "github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/cli/utils"
"github.com/alcionai/corso/src/internal/kopia"
"github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/pkg/backup"
"github.com/alcionai/corso/src/pkg/backup/details"
@ -295,6 +296,10 @@ func runDetailsOneDriveCmd(
) (*details.Details, error) {
d, _, err := r.BackupDetails(ctx, backupID)
if err != nil {
if errors.Is(err, kopia.ErrNotFound) {
return nil, errors.Errorf("no backup exists with the id %s", backupID)
}
return nil, errors.Wrap(err, "Failed to get backup details in the repository")
}

View File

@ -14,6 +14,7 @@ import (
const stableIDKey = "stableID"
var (
ErrNotFound = errors.New("not found")
errNoModelStoreID = errors.New("model has no ModelStoreID")
errNoStableID = errors.New("model has no StableID")
errBadTagKey = errors.New("tag key overlaps with required key")
@ -219,8 +220,7 @@ func (ms *ModelStore) GetIDsForType(
}
// getModelStoreID gets the ModelStoreID of the model with the given
// StableID. Returns github.com/kopia/kopia/repo/manifest.ErrNotFound if no
// model was found. Returns an error if the given StableID is empty or more than
// StableID. Returns an error if the given StableID is empty or more than
// one model has the same StableID.
func (ms *ModelStore) getModelStoreID(
ctx context.Context,
@ -243,7 +243,7 @@ func (ms *ModelStore) getModelStoreID(
}
if len(metadata) == 0 {
return "", errors.Wrap(manifest.ErrNotFound, "getting ModelStoreID")
return "", errors.Wrap(ErrNotFound, "getting ModelStoreID")
}
if len(metadata) != 1 {
@ -257,10 +257,9 @@ func (ms *ModelStore) getModelStoreID(
return metadata[0].ID, nil
}
// Get deserializes the model with the given StableID into data. Returns
// github.com/kopia/kopia/repo/manifest.ErrNotFound if no model was found.
// Returns and error if the persisted model has a different type than expected
// or if multiple models have the same StableID.
// Get deserializes the model with the given StableID into data.
// Returns an error if the persisted model has a different type
// than expected or if multiple models have the same StableID.
func (ms *ModelStore) Get(
ctx context.Context,
s model.Schema,
@ -276,12 +275,11 @@ func (ms *ModelStore) Get(
return err
}
return ms.GetWithModelStoreID(ctx, s, modelID, data)
return transmuteErr(ms.GetWithModelStoreID(ctx, s, modelID, data))
}
// GetWithModelStoreID deserializes the model with the given ModelStoreID into
// data. Returns github.com/kopia/kopia/repo/manifest.ErrNotFound if no model
// was found. Returns and error if the persisted model has a different type than
// data. Returns and error if the persisted model has a different type than
// expected.
func (ms *ModelStore) GetWithModelStoreID(
ctx context.Context,
@ -298,10 +296,8 @@ func (ms *ModelStore) GetWithModelStoreID(
}
metadata, err := ms.c.GetManifest(ctx, id, data)
// TODO(ashmrtnz): Should probably return some recognizable, non-kopia error
// if not found. That way kopia doesn't need to be imported to higher layers.
if err != nil {
return errors.Wrap(err, "getting model data")
return errors.Wrap(transmuteErr(err), "getting model data")
}
if metadata.Labels[manifest.TypeLabelKey] != s.String() {
@ -423,7 +419,7 @@ func (ms *ModelStore) Delete(ctx context.Context, s model.Schema, id model.Stabl
latest, err := ms.getModelStoreID(ctx, s, id)
if err != nil {
if errors.Is(err, manifest.ErrNotFound) {
if errors.Is(err, ErrNotFound) {
return nil
}
@ -452,3 +448,12 @@ func (ms *ModelStore) DeleteWithModelStoreID(ctx context.Context, id manifest.ID
return errors.Wrap(err, "deleting model")
}
func transmuteErr(err error) error {
switch {
case errors.Is(err, manifest.ErrNotFound):
return ErrNotFound
default:
return err
}
}

View File

@ -335,9 +335,9 @@ func (suite *ModelStoreIntegrationSuite) TestPutGet_WithTags() {
func (suite *ModelStoreIntegrationSuite) TestGet_NotFoundErrors() {
t := suite.T()
assert.ErrorIs(t, suite.m.Get(suite.ctx, model.BackupOpSchema, "baz", nil), manifest.ErrNotFound)
assert.ErrorIs(t, suite.m.Get(suite.ctx, model.BackupOpSchema, "baz", nil), ErrNotFound)
assert.ErrorIs(
t, suite.m.GetWithModelStoreID(suite.ctx, model.BackupOpSchema, "baz", nil), manifest.ErrNotFound)
t, suite.m.GetWithModelStoreID(suite.ctx, model.BackupOpSchema, "baz", nil), ErrNotFound)
}
func (suite *ModelStoreIntegrationSuite) TestPutGetOfType() {
@ -580,7 +580,7 @@ func (suite *ModelStoreIntegrationSuite) TestPutUpdate() {
}
err = m.GetWithModelStoreID(ctx, theModelType, oldModelID, nil)
assert.ErrorIs(t, err, manifest.ErrNotFound)
assert.ErrorIs(t, err, ErrNotFound)
})
}
}
@ -640,7 +640,7 @@ func (suite *ModelStoreIntegrationSuite) TestPutDelete() {
returned := &fooModel{}
err := suite.m.GetWithModelStoreID(suite.ctx, theModelType, foo.ModelStoreID, returned)
assert.ErrorIs(t, err, manifest.ErrNotFound)
assert.ErrorIs(t, err, ErrNotFound)
}
func (suite *ModelStoreIntegrationSuite) TestPutDelete_BadIDsNoop() {
@ -725,7 +725,7 @@ func (suite *ModelStoreRegressionSuite) TestFailDuringWriteSessionHasNoVisibleEf
assert.ErrorIs(t, err, assert.AnError)
err = m.GetWithModelStoreID(ctx, theModelType, newID, nil)
assert.ErrorIs(t, err, manifest.ErrNotFound)
assert.ErrorIs(t, err, ErrNotFound)
returned := &fooModel{}
require.NoError(