diff --git a/src/internal/m365/collection/site/handlers.go b/src/internal/m365/collection/site/handlers.go index fac778de7..4ce482e59 100644 --- a/src/internal/m365/collection/site/handlers.go +++ b/src/internal/m365/collection/site/handlers.go @@ -6,6 +6,7 @@ import ( "github.com/microsoftgraph/msgraph-sdk-go/models" "github.com/alcionai/corso/src/pkg/backup/details" + "github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/services/m365/api" ) @@ -32,6 +33,7 @@ type PostLister interface { ctx context.Context, listName string, storedListData []byte, + errs *fault.Bus, ) (models.Listable, error) } diff --git a/src/internal/m365/collection/site/lists_handler.go b/src/internal/m365/collection/site/lists_handler.go index a9e130974..72b282101 100644 --- a/src/internal/m365/collection/site/lists_handler.go +++ b/src/internal/m365/collection/site/lists_handler.go @@ -6,6 +6,7 @@ import ( "github.com/microsoftgraph/msgraph-sdk-go/models" "github.com/alcionai/corso/src/pkg/backup/details" + "github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/services/m365/api" ) @@ -52,8 +53,9 @@ func (rh listsRestoreHandler) PostList( ctx context.Context, listName string, storedListData []byte, + errs *fault.Bus, ) (models.Listable, error) { - return rh.ac.PostList(ctx, rh.protectedResource, listName, storedListData) + return rh.ac.PostList(ctx, rh.protectedResource, listName, storedListData, errs) } func (rh listsRestoreHandler) DeleteList( diff --git a/src/internal/m365/collection/site/restore.go b/src/internal/m365/collection/site/restore.go index a69e3bc5d..334dd486d 100644 --- a/src/internal/m365/collection/site/restore.go +++ b/src/internal/m365/collection/site/restore.go @@ -137,6 +137,7 @@ func restoreListItem( rh restoreHandler, itemData data.Item, siteID, destName string, + errs *fault.Bus, ) (details.ItemInfo, error) { ctx, end := diagnostics.Span(ctx, "m365:sharepoint:restoreList", diagnostics.Label("item_uuid", itemData.ID())) defer end() @@ -156,7 +157,7 @@ func restoreListItem( newName := fmt.Sprintf("%s_%s", destName, listName) // Restore to List base to M365 back store - restoredList, err := rh.PostList(ctx, newName, bytes) + restoredList, err := rh.PostList(ctx, newName, bytes, errs) if err != nil { return dii, graph.Wrap(ctx, err, "restoring list") } @@ -207,7 +208,8 @@ func RestoreListCollection( rh, itemData, siteID, - restoreContainerName) + restoreContainerName, + errs) if err != nil && errors.Is(err, api.ErrCannotCreateWebTemplateExtension) { continue diff --git a/src/internal/m365/collection/site/restore_test.go b/src/internal/m365/collection/site/restore_test.go index 438c992b2..ebbfc9c4f 100644 --- a/src/internal/m365/collection/site/restore_test.go +++ b/src/internal/m365/collection/site/restore_test.go @@ -25,6 +25,7 @@ import ( "github.com/alcionai/corso/src/pkg/control" "github.com/alcionai/corso/src/pkg/control/testdata" "github.com/alcionai/corso/src/pkg/count" + "github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/services/m365/api" "github.com/alcionai/corso/src/pkg/services/m365/api/graph" ) @@ -81,7 +82,7 @@ func (suite *SharePointRestoreSuite) TestListCollection_Restore() { suite.creds, "genericList") - deets, err := restoreListItem(ctx, lrh, mockData, suite.siteID, destName) + deets, err := restoreListItem(ctx, lrh, mockData, suite.siteID, destName, fault.New(true)) require.NoError(t, err, clues.ToCore(err)) assert.Equal(t, fmt.Sprintf("%s_%s", destName, testName), deets.SharePoint.List.Name) @@ -102,7 +103,7 @@ func (suite *SharePointRestoreSuite) TestListCollection_Restore_invalidListTempl suite.creds, api.WebTemplateExtensionsListTemplateName) - _, err := restoreListItem(ctx, lrh, mockData, suite.siteID, destName) + _, err := restoreListItem(ctx, lrh, mockData, suite.siteID, destName, fault.New(true)) require.Error(t, err) assert.Contains(t, err.Error(), api.ErrCannotCreateWebTemplateExtension.Error()) } diff --git a/src/pkg/services/m365/api/lists.go b/src/pkg/services/m365/api/lists.go index f8f97c2cb..4d79e01c6 100644 --- a/src/pkg/services/m365/api/lists.go +++ b/src/pkg/services/m365/api/lists.go @@ -10,6 +10,7 @@ import ( "github.com/alcionai/corso/src/internal/common/keys" "github.com/alcionai/corso/src/internal/common/ptr" "github.com/alcionai/corso/src/pkg/backup/details" + "github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/services/m365/api/graph" ) @@ -230,8 +231,12 @@ func (c Lists) PostList( siteID string, listName string, oldListByteArray []byte, + errs *fault.Bus, ) (models.Listable, error) { - newListName := listName + var ( + newListName = listName + el = errs.Local() + ) oldList, err := BytesToListable(oldListByteArray) if err != nil { @@ -280,18 +285,14 @@ func (c Lists) PostList( siteID, ptr.Val(restoredList.GetId()), listItems) - if err == nil { - restoredList.SetItems(listItems) - return restoredList, nil + if err != nil { + err = graph.Wrap(ctx, err, "creating list item") + el.AddRecoverable(ctx, err) } - // [TODO](hitesh) double check if we need to: - // 1. rollback the entire list - // 2. restore as much list items possible and add recoverables to fault bus - // rollback list creation - err = c.DeleteList(ctx, siteID, ptr.Val(restoredList.GetId())) + restoredList.SetItems(listItems) - return nil, graph.Wrap(ctx, err, "deleting restored list after items creation failure").OrNil() + return restoredList, nil } func (c Lists) PostListItems( diff --git a/src/pkg/services/m365/api/lists_test.go b/src/pkg/services/m365/api/lists_test.go index df6bd27c5..b55cfc808 100644 --- a/src/pkg/services/m365/api/lists_test.go +++ b/src/pkg/services/m365/api/lists_test.go @@ -18,6 +18,7 @@ import ( "github.com/alcionai/corso/src/internal/tester/tconfig" "github.com/alcionai/corso/src/pkg/backup/details" "github.com/alcionai/corso/src/pkg/control/testdata" + "github.com/alcionai/corso/src/pkg/fault" "github.com/alcionai/corso/src/pkg/services/m365/api/graph" graphTD "github.com/alcionai/corso/src/pkg/services/m365/api/graph/testdata" ) @@ -734,11 +735,11 @@ func (suite *ListsAPIIntgSuite) TestLists_PostList() { oldListByteArray, err := writer.GetSerializedContent() require.NoError(t, err) - newList, err := acl.PostList(ctx, siteID, listName, oldListByteArray) + newList, err := acl.PostList(ctx, siteID, listName, oldListByteArray, fault.New(true)) require.NoError(t, err, clues.ToCore(err)) assert.Equal(t, listName, ptr.Val(newList.GetDisplayName())) - _, err = acl.PostList(ctx, siteID, listName, oldListByteArray) + _, err = acl.PostList(ctx, siteID, listName, oldListByteArray, fault.New(true)) require.Error(t, err) newListItems := newList.GetItems() @@ -785,7 +786,7 @@ func (suite *ListsAPIIntgSuite) TestLists_PostList_invalidTemplate() { oldListByteArray, err := writer.GetSerializedContent() require.NoError(t, err) - _, err = acl.PostList(ctx, siteID, listName, oldListByteArray) + _, err = acl.PostList(ctx, siteID, listName, oldListByteArray, fault.New(true)) require.Error(t, err) assert.Equal(t, ErrCannotCreateWebTemplateExtension.Error(), err.Error()) } @@ -813,7 +814,7 @@ func (suite *ListsAPIIntgSuite) TestLists_DeleteList() { oldListByteArray, err := writer.GetSerializedContent() require.NoError(t, err) - newList, err := acl.PostList(ctx, siteID, listName, oldListByteArray) + newList, err := acl.PostList(ctx, siteID, listName, oldListByteArray, fault.New(true)) require.NoError(t, err, clues.ToCore(err)) assert.Equal(t, listName, ptr.Val(newList.GetDisplayName()))