remove wrap and append support (#2589)

## Does this PR need a docs update or release note?

- [x]  No 

## Type of change

- [x] 🧹 Tech Debt/Cleanup

## Issue(s)

* #1970

## Test Plan

- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Keepers 2023-03-07 18:24:48 -07:00 committed by GitHub
parent 30d9705829
commit 1ca49c53a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 274 additions and 529 deletions

View File

@ -97,7 +97,7 @@ func (c Users) GetAll(ctx context.Context, errs *fault.Bus) ([]models.Userable,
resp, err = service.Client().Users().Get(ctx, userOptions(&userFilterNoGuests))
if err != nil {
return nil, clues.Wrap(err, "getting all users").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting all users")
}
iter, err := msgraphgocore.NewPageIterator(
@ -105,7 +105,7 @@ func (c Users) GetAll(ctx context.Context, errs *fault.Bus) ([]models.Userable,
service.Adapter(),
models.CreateUserCollectionResponseFromDiscriminatorValue)
if err != nil {
return nil, clues.Wrap(err, "creating users iterator").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "creating users iterator")
}
var (
@ -120,7 +120,7 @@ func (c Users) GetAll(ctx context.Context, errs *fault.Bus) ([]models.Userable,
u, err := validateUser(item)
if err != nil {
el.AddRecoverable(clues.Wrap(err, "validating user").WithClues(ctx).With(graph.ErrData(err)...))
el.AddRecoverable(graph.Wrap(ctx, err, "validating user"))
} else {
us = append(us, u)
}
@ -129,7 +129,7 @@ func (c Users) GetAll(ctx context.Context, errs *fault.Bus) ([]models.Userable,
}
if err := iter.Iterate(ctx, iterator); err != nil {
return nil, clues.Wrap(err, "iterating all users").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "iterating all users")
}
return us, el.Failure()
@ -144,7 +144,7 @@ func (c Users) GetByID(ctx context.Context, userID string) (models.Userable, err
resp, err = c.stable.Client().UsersById(userID).Get(ctx, nil)
if err != nil {
return nil, clues.Wrap(err, "getting user").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting user")
}
return resp, err
@ -163,7 +163,7 @@ func (c Users) GetInfo(ctx context.Context, userID string) (*UserInfo, error) {
if err != nil {
if !graph.IsErrExchangeMailFolderNotFound(err) {
return nil, clues.Wrap(err, "getting user's mail folder").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting user's mail folder")
}
delete(userInfo.DiscoveredServices, path.ExchangeService)

View File

@ -49,7 +49,7 @@ func (c Contacts) CreateContactFolder(
mdl, err := c.stable.Client().UsersById(user).ContactFolders().Post(ctx, requestBody, nil)
if err != nil {
return nil, clues.Wrap(err, "creating contact folder").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "creating contact folder")
}
return mdl, nil
@ -62,7 +62,7 @@ func (c Contacts) DeleteContainer(
) error {
err := c.stable.Client().UsersById(user).ContactFoldersById(folderID).Delete(ctx, nil)
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
return nil
@ -76,7 +76,7 @@ func (c Contacts) GetItem(
) (serialization.Parsable, *details.ExchangeInfo, error) {
cont, err := c.stable.Client().UsersById(user).ContactsById(itemID).Get(ctx, nil)
if err != nil {
return nil, nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, graph.Stack(ctx, err)
}
return cont, ContactInfo(cont), nil
@ -88,12 +88,12 @@ func (c Contacts) GetContainerByID(
) (graph.Container, error) {
ofcf, err := optionsForContactFolderByID([]string{"displayName", "parentFolderId"})
if err != nil {
return nil, clues.Wrap(err, "setting contact folder options").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "setting contact folder options")
}
resp, err := c.stable.Client().UsersById(userID).ContactFoldersById(dirID).Get(ctx, ofcf)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
return resp, nil
@ -112,17 +112,14 @@ func (c Contacts) EnumerateContainers(
) error {
service, err := c.service()
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
fields := []string{"displayName", "parentFolderId"}
ofcf, err := optionsForContactChildFolders(fields)
if err != nil {
return clues.Wrap(err, "setting contact child folder options").
WithClues(ctx).
With(graph.ErrData(err)...).
With("options_fields", fields)
return graph.Wrap(ctx, err, "setting contact child folder options")
}
el := errs.Local()
@ -138,7 +135,7 @@ func (c Contacts) EnumerateContainers(
resp, err := builder.Get(ctx, ofcf)
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
for _, fold := range resp.GetValue() {
@ -147,11 +144,7 @@ func (c Contacts) EnumerateContainers(
}
if err := checkIDAndName(fold); err != nil {
el.AddRecoverable(clues.Stack(err).
WithClues(ctx).
With(graph.ErrData(err)...).
Label(fault.LabelForceNoBackupCreation))
errs.AddRecoverable(graph.Stack(ctx, err).Label(fault.LabelForceNoBackupCreation))
continue
}
@ -162,11 +155,7 @@ func (c Contacts) EnumerateContainers(
temp := graph.NewCacheFolder(fold, nil, nil)
if err := fn(temp); err != nil {
el.AddRecoverable(clues.Stack(err).
WithClues(fctx).
With(graph.ErrData(err)...).
Label(fault.LabelForceNoBackupCreation))
errs.AddRecoverable(graph.Stack(fctx, err).Label(fault.LabelForceNoBackupCreation))
continue
}
}
@ -197,7 +186,7 @@ type contactPager struct {
func (p *contactPager) getPage(ctx context.Context) (api.DeltaPageLinker, error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
return resp, nil
@ -217,7 +206,7 @@ func (c Contacts) GetAddedAndRemovedItemIDs(
) ([]string, []string, DeltaUpdate, error) {
service, err := c.service()
if err != nil {
return nil, nil, DeltaUpdate{}, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, DeltaUpdate{}, graph.Stack(ctx, err)
}
var resetDelta bool
@ -232,7 +221,7 @@ func (c Contacts) GetAddedAndRemovedItemIDs(
return nil,
nil,
DeltaUpdate{},
clues.Wrap(err, "setting contact folder options").WithClues(ctx).With(graph.ErrData(err)...)
graph.Wrap(ctx, err, "setting contact folder options")
}
if len(oldDelta) > 0 {
@ -250,7 +239,7 @@ func (c Contacts) GetAddedAndRemovedItemIDs(
// only return on error if it is NOT a delta issue.
// on bad deltas we retry the call with the regular builder
if !graph.IsErrInvalidDelta(err) {
return nil, nil, DeltaUpdate{}, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, DeltaUpdate{}, graph.Stack(ctx, err)
}
resetDelta = true
@ -303,12 +292,12 @@ func (c Contacts) Serialize(
defer writer.Close()
if err = writer.WriteObjectValue("", contact); err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
bs, err := writer.GetSerializedContent()
if err != nil {
return nil, clues.Wrap(err, "serializing contact").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "serializing contact")
}
return bs, nil

View File

@ -50,7 +50,7 @@ func (c Events) CreateCalendar(
mdl, err := c.stable.Client().UsersById(user).Calendars().Post(ctx, requestbody, nil)
if err != nil {
return nil, clues.Wrap(err, "creating calendar").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "creating calendar")
}
return mdl, nil
@ -64,7 +64,7 @@ func (c Events) DeleteContainer(
) error {
err := c.stable.Client().UsersById(user).CalendarsById(calendarID).Delete(ctx, nil)
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
return nil
@ -76,17 +76,17 @@ func (c Events) GetContainerByID(
) (graph.Container, error) {
service, err := c.service()
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
ofc, err := optionsForCalendarsByID([]string{"name", "owner"})
if err != nil {
return nil, clues.Wrap(err, "setting event calendar options").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "setting event calendar options")
}
cal, err := service.Client().UsersById(userID).CalendarsById(containerID).Get(ctx, ofc)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err).WithClues(ctx)
}
return graph.CalendarDisplayable{Calendarable: cal}, nil
@ -105,7 +105,7 @@ func (c Events) GetItem(
event, err = c.stable.Client().UsersById(user).EventsById(itemID).Get(ctx, nil)
if err != nil {
return nil, nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, graph.Stack(ctx, err)
}
if *event.GetHasAttachments() || HasAttachments(event.GetBody()) {
@ -122,7 +122,7 @@ func (c Events) GetItem(
Attachments().
Get(ctx, options)
if err != nil {
return nil, nil, clues.Wrap(err, "event attachment download").WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, graph.Wrap(ctx, err, "event attachment download")
}
event.SetAttachments(attached.GetValue())
@ -144,12 +144,12 @@ func (c Events) EnumerateContainers(
) error {
service, err := c.service()
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
ofc, err := optionsForCalendars([]string{"name"})
if err != nil {
return clues.Wrap(err, "setting calendar options").WithClues(ctx).With(graph.ErrData(err)...)
return graph.Wrap(ctx, err, "setting calendar options")
}
el := errs.Local()
@ -162,7 +162,7 @@ func (c Events) EnumerateContainers(
resp, err := builder.Get(ctx, ofc)
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
for _, cal := range resp.GetValue() {
@ -172,11 +172,7 @@ func (c Events) EnumerateContainers(
cd := CalendarDisplayable{Calendarable: cal}
if err := checkIDAndName(cd); err != nil {
el.AddRecoverable(clues.Stack(err).
WithClues(ctx).
With(graph.ErrData(err)...).
Label(fault.LabelForceNoBackupCreation))
errs.AddRecoverable(graph.Stack(ctx, err).Label(fault.LabelForceNoBackupCreation))
continue
}
@ -190,11 +186,7 @@ func (c Events) EnumerateContainers(
path.Builder{}.Append(ptr.Val(cd.GetId())), // storage path
path.Builder{}.Append(ptr.Val(cd.GetDisplayName()))) // display location
if err := fn(temp); err != nil {
el.AddRecoverable(clues.Stack(err).
WithClues(fctx).
With(graph.ErrData(err)...).
Label(fault.LabelForceNoBackupCreation))
errs.AddRecoverable(graph.Stack(fctx, err).Label(fault.LabelForceNoBackupCreation))
continue
}
}
@ -229,7 +221,7 @@ type eventPager struct {
func (p *eventPager) getPage(ctx context.Context) (api.DeltaPageLinker, error) {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
return resp, nil
@ -272,7 +264,7 @@ func (c Events) GetAddedAndRemovedItemIDs(
// only return on error if it is NOT a delta issue.
// on bad deltas we retry the call with the regular builder
if !graph.IsErrInvalidDelta(err) {
return nil, nil, DeltaUpdate{}, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, DeltaUpdate{}, graph.Stack(ctx, err)
}
resetDelta = true
@ -335,12 +327,12 @@ func (c Events) Serialize(
defer writer.Close()
if err = writer.WriteObjectValue("", event); err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
bs, err := writer.GetSerializedContent()
if err != nil {
return nil, clues.Wrap(err, "serializing event").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "serializing event")
}
return bs, nil

View File

@ -50,7 +50,7 @@ func (c Mail) CreateMailFolder(
mdl, err := c.stable.Client().UsersById(user).MailFolders().Post(ctx, requestBody, nil)
if err != nil {
return nil, clues.Wrap(err, "creating mail folder").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "creating mail folder")
}
return mdl, nil
@ -62,7 +62,7 @@ func (c Mail) CreateMailFolderWithParent(
) (models.MailFolderable, error) {
service, err := c.service()
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
isHidden := false
@ -77,7 +77,7 @@ func (c Mail) CreateMailFolderWithParent(
ChildFolders().
Post(ctx, requestBody, nil)
if err != nil {
return nil, clues.Wrap(err, "creating nested mail folder").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "creating nested mail folder")
}
return mdl, nil
@ -91,7 +91,7 @@ func (c Mail) DeleteContainer(
) error {
err := c.stable.Client().UsersById(user).MailFoldersById(folderID).Delete(ctx, nil)
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
return nil
@ -103,17 +103,17 @@ func (c Mail) GetContainerByID(
) (graph.Container, error) {
service, err := c.service()
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
ofmf, err := optionsForMailFoldersItem([]string{"displayName", "parentFolderId"})
if err != nil {
return nil, clues.Wrap(err, "setting mail folder options").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "setting mail folder options")
}
resp, err := service.Client().UsersById(userID).MailFoldersById(dirID).Get(ctx, ofmf)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
return resp, nil
@ -128,7 +128,7 @@ func (c Mail) GetItem(
) (serialization.Parsable, *details.ExchangeInfo, error) {
mail, err := c.stable.Client().UsersById(user).MessagesById(itemID).Get(ctx, nil)
if err != nil {
return nil, nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, graph.Stack(ctx, err)
}
if *mail.GetHasAttachments() || HasAttachments(mail.GetBody()) {
@ -145,7 +145,7 @@ func (c Mail) GetItem(
Attachments().
Get(ctx, options)
if err != nil {
return nil, nil, clues.Wrap(err, "mail attachment download").WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, graph.Wrap(ctx, err, "mail attachment download")
}
mail.SetAttachments(attached.GetValue())
@ -167,7 +167,7 @@ func (c Mail) EnumerateContainers(
) error {
service, err := c.service()
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
el := errs.Local()
@ -183,7 +183,7 @@ func (c Mail) EnumerateContainers(
resp, err := builder.Get(ctx, nil)
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
for _, v := range resp.GetValue() {
@ -198,11 +198,7 @@ func (c Mail) EnumerateContainers(
temp := graph.NewCacheFolder(v, nil, nil)
if err := fn(temp); err != nil {
el.AddRecoverable(clues.Stack(err).
WithClues(fctx).
With(graph.ErrData(err)...).
Label(fault.LabelForceNoBackupCreation))
errs.AddRecoverable(graph.Stack(fctx, err).Label(fault.LabelForceNoBackupCreation))
continue
}
}
@ -233,7 +229,7 @@ type mailPager struct {
func (p *mailPager) getPage(ctx context.Context) (api.DeltaPageLinker, error) {
page, err := p.builder.Get(ctx, p.options)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
return page, nil
@ -271,7 +267,7 @@ func (c Mail) GetAddedAndRemovedItemIDs(
return nil,
nil,
DeltaUpdate{},
clues.Wrap(err, "setting contact folder options").WithClues(ctx).With(graph.ErrData(err)...)
graph.Wrap(ctx, err, "setting contact folder options")
}
if len(oldDelta) > 0 {
@ -341,12 +337,12 @@ func (c Mail) Serialize(
defer writer.Close()
if err = writer.WriteObjectValue("", msg); err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
bs, err := writer.GetSerializedContent()
if err != nil {
return nil, clues.Wrap(err, "serializing email").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "serializing email")
}
return bs, nil

View File

@ -74,14 +74,14 @@ func getItemsAddedAndRemovedFromContainer(
// get the next page of data, check for standard errors
resp, err := pager.getPage(ctx)
if err != nil {
return nil, nil, deltaURL, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, deltaURL, graph.Stack(ctx, err)
}
// each category type responds with a different interface, but all
// of them comply with GetValue, which is where we'll get our item data.
items, err := pager.valuesIn(resp)
if err != nil {
return nil, nil, "", clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, "", graph.Stack(ctx, err)
}
itemCount += len(items)

View File

@ -3,7 +3,6 @@ package exchange
import (
"context"
"github.com/alcionai/clues"
"github.com/microsoftgraph/msgraph-sdk-go/models"
msusers "github.com/microsoftgraph/msgraph-sdk-go/users"
@ -44,7 +43,7 @@ func (mau *mailAttachmentUploader) uploadSmallAttachment(ctx context.Context, at
Attachments().
Post(ctx, attach, nil)
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
return nil
@ -68,7 +67,7 @@ func (mau *mailAttachmentUploader) uploadSession(
CreateUploadSession().
Post(ctx, session, nil)
if err != nil {
return nil, clues.Wrap(err, "uploading mail attachment").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "uploading mail attachment")
}
return r, nil
@ -94,7 +93,7 @@ func (eau *eventAttachmentUploader) uploadSmallAttachment(ctx context.Context, a
Attachments().
Post(ctx, attach, nil)
if err != nil {
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return graph.Stack(ctx, err)
}
return nil
@ -116,7 +115,7 @@ func (eau *eventAttachmentUploader) uploadSession(
CreateUploadSession().
Post(ctx, session, nil)
if err != nil {
return nil, clues.Wrap(err, "uploading event attachment").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "uploading event attachment")
}
return r, nil

View File

@ -13,7 +13,6 @@ import (
"github.com/alcionai/corso/src/internal/connector/exchange/api"
"github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/connector/mockconnector"
"github.com/alcionai/corso/src/internal/connector/support"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/control"
@ -89,7 +88,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreContact() {
control.Copy,
folderID,
userID)
assert.NoError(t, err, support.ConnectorStackErrorTrace(err))
assert.NoError(t, err)
assert.NotNil(t, info, "contact item info")
}
@ -123,7 +122,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreEvent() {
calendarID,
userID,
fault.New(true))
assert.NoError(t, err, support.ConnectorStackErrorTrace(err))
assert.NoError(t, err)
assert.NotNil(t, info, "event item info")
}
@ -352,7 +351,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
destination,
userID,
fault.New(true))
assert.NoError(t, err, support.ConnectorStackErrorTrace(err))
assert.NoError(t, err)
assert.NotNil(t, info, "item info was not populated")
assert.NotNil(t, deleters)
assert.NoError(t, deleters[test.category].DeleteContainer(ctx, userID, destination))

View File

@ -70,14 +70,14 @@ func RestoreExchangeContact(
) (*details.ExchangeInfo, error) {
contact, err := support.CreateContactFromBytes(bits)
if err != nil {
return nil, clues.Wrap(err, "creating contact from bytes").WithClues(ctx)
return nil, graph.Wrap(ctx, err, "creating contact from bytes")
}
ctx = clues.Add(ctx, "item_id", ptr.Val(contact.GetId()))
response, err := service.Client().UsersById(user).ContactFoldersById(destination).Contacts().Post(ctx, contact, nil)
if err != nil {
return nil, clues.Wrap(err, "uploading Contact").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "uploading Contact")
}
if response == nil {
@ -125,7 +125,7 @@ func RestoreExchangeEvent(
response, err := service.Client().UsersById(user).CalendarsById(destination).Events().Post(ctx, transformedEvent, nil)
if err != nil {
return nil, clues.Wrap(err, "uploading event").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "uploading event")
}
if response == nil {
@ -249,7 +249,7 @@ func SendMailToBackStore(
response, err := service.Client().UsersById(user).MailFoldersById(destination).Messages().Post(ctx, message, nil)
if err != nil {
return clues.Wrap(err, "restoring mail").WithClues(ctx).With(graph.ErrData(err)...)
return graph.Wrap(ctx, err, "restoring mail")
}
if response == nil {
@ -609,7 +609,7 @@ func establishMailRestoreLocation(
temp, err := ac.Mail().CreateMailFolderWithParent(ctx, user, folder, folderID)
if err != nil {
// Should only error if cache malfunctions or incorrect parameters
return "", errors.Wrap(err, support.ConnectorStackErrorTrace(err))
return "", err
}
folderID = *temp.GetId()
@ -658,7 +658,7 @@ func establishContactsRestoreLocation(
temp, err := ac.Contacts().CreateContactFolder(ctx, user, folders[0])
if err != nil {
return "", errors.Wrap(err, support.ConnectorStackErrorTrace(err))
return "", err
}
folderID := *temp.GetId()
@ -695,7 +695,7 @@ func establishEventsRestoreLocation(
temp, err := ac.Events().CreateCalendar(ctx, user, folders[0])
if err != nil {
return "", errors.Wrap(err, support.ConnectorStackErrorTrace(err))
return "", err
}
folderID := *temp.GetId()

View File

@ -56,18 +56,20 @@ func (suite *BetaClientSuite) TestCreateBetaClient() {
func (suite *BetaClientSuite) TestBasicClientGetFunctionality() {
ctx, flush := tester.NewContext()
defer flush()
t := suite.T()
adpt, err := graph.CreateAdapter(
suite.credentials.AzureTenantID,
suite.credentials.AzureClientID,
suite.credentials.AzureClientSecret,
)
suite.credentials.AzureClientSecret)
require.NoError(t, err)
client := NewBetaClient(adpt)
require.NotNil(t, client)
siteID := tester.M365SiteID(t)
// TODO(dadams39) document allowable calls in main
collection, err := client.SitesById(siteID).Pages().Get(ctx, nil)
// Ensures that the client is able to receive data from beta

View File

@ -12,7 +12,9 @@ import (
"github.com/pkg/errors"
"golang.org/x/exp/slices"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/common/ptr"
)
// ---------------------------------------------------------------------------
@ -43,6 +45,17 @@ var (
Err500InternalServerError = errors.New("500 Internal Server Error")
)
var (
mysiteURLNotFound = "unable to retrieve user's mysite url"
mysiteNotFound = "user's mysite not found"
)
var Labels = struct {
MysiteNotFound string
}{
MysiteNotFound: "mysite_not_found",
}
// The folder or item was deleted between the time we identified
// it and when we tried to fetch data for it.
type ErrDeletedInFlight struct {
@ -196,43 +209,74 @@ func hasErrorCode(err error, codes ...string) bool {
return slices.Contains(lcodes, strings.ToLower(*oDataError.GetError().GetCode()))
}
// ErrData is a helper function that extracts ODataError metadata from
// the error. If the error is not an ODataError type, returns an empty
// slice. The returned value is guaranteed to be an even-length pairing
// of key, value tuples.
func ErrData(e error) []any {
result := make([]any, 0)
// Wrap is a helper function that extracts ODataError metadata from
// the error. If the error is not an ODataError type, returns the error.
func Wrap(ctx context.Context, e error, msg string) *clues.Err {
if e == nil {
return result
return nil
}
odErr, ok := e.(odataerrors.ODataErrorable)
if !ok {
return result
return clues.Wrap(e, msg).WithClues(ctx)
}
// Get MainError
mainErr := odErr.GetError()
data, innerMsg := errData(odErr)
result = appendIf(result, "odataerror_code", mainErr.GetCode())
result = appendIf(result, "odataerror_message", mainErr.GetMessage())
result = appendIf(result, "odataerror_target", mainErr.GetTarget())
return setLabels(clues.Wrap(e, msg).WithClues(ctx).With(data...), innerMsg)
}
// Stack is a helper function that extracts ODataError metadata from
// the error. If the error is not an ODataError type, returns the error.
func Stack(ctx context.Context, e error) *clues.Err {
if e == nil {
return nil
}
odErr, ok := e.(odataerrors.ODataErrorable)
if !ok {
return clues.Stack(e).WithClues(ctx)
}
data, innerMsg := errData(odErr)
return setLabels(clues.Stack(e).WithClues(ctx).With(data...), innerMsg)
}
func setLabels(err *clues.Err, msg string) *clues.Err {
if strings.Contains(msg, mysiteNotFound) || strings.Contains(msg, mysiteURLNotFound) {
err = err.Label(Labels.MysiteNotFound)
}
return err
}
func errData(err odataerrors.ODataErrorable) ([]any, string) {
data := make([]any, 0)
// Get MainError
mainErr := err.GetError()
data = appendIf(data, "odataerror_code", mainErr.GetCode())
data = appendIf(data, "odataerror_message", mainErr.GetMessage())
data = appendIf(data, "odataerror_target", mainErr.GetTarget())
msgConcat := ptr.Val(mainErr.GetMessage()) + ptr.Val(mainErr.GetCode())
for i, d := range mainErr.GetDetails() {
pfx := fmt.Sprintf("odataerror_details_%d_", i)
result = appendIf(result, pfx+"code", d.GetCode())
result = appendIf(result, pfx+"message", d.GetMessage())
result = appendIf(result, pfx+"target", d.GetTarget())
data = appendIf(data, pfx+"code", d.GetCode())
data = appendIf(data, pfx+"message", d.GetMessage())
data = appendIf(data, pfx+"target", d.GetTarget())
msgConcat += ptr.Val(d.GetMessage())
}
inner := mainErr.GetInnererror()
if inner != nil {
result = appendIf(result, "odataerror_inner_cli_req_id", inner.GetClientRequestId())
result = appendIf(result, "odataerror_inner_req_id", inner.GetRequestId())
data = appendIf(data, "odataerror_inner_cli_req_id", inner.GetClientRequestId())
data = appendIf(data, "odataerror_inner_req_id", inner.GetRequestId())
}
return result
return data, strings.ToLower(msgConcat)
}
func appendIf(a []any, k string, v *string) []any {

View File

@ -6,7 +6,6 @@ import (
"strconv"
"time"
"github.com/alcionai/clues"
backoff "github.com/cenkalti/backoff/v4"
khttp "github.com/microsoft/kiota-http-go"
)
@ -50,10 +49,7 @@ func (middleware RetryHandler) retryRequest(
response, err := pipeline.Next(req, middlewareIndex)
if err != nil && !IsErrTimeout(err) {
return response, clues.Stack(err).
WithClues(ctx).
With("retry_count", executionCount).
With(ErrData(err)...)
return response, Stack(ctx, err).With("retry_count", executionCount)
}
return middleware.retryRequest(ctx,
@ -68,10 +64,7 @@ func (middleware RetryHandler) retryRequest(
}
if respErr != nil {
return nil, clues.Stack(respErr).
WithClues(ctx).
With("retry_count", executionCount).
With(ErrData(respErr)...)
return nil, Stack(ctx, respErr).With("retry_count", executionCount)
}
return resp, nil

View File

@ -8,7 +8,6 @@ import (
"time"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
"github.com/alcionai/clues"
backoff "github.com/cenkalti/backoff/v4"
"github.com/microsoft/kiota-abstractions-go/serialization"
ka "github.com/microsoft/kiota-authentication-azure-go"
@ -343,7 +342,7 @@ func (middleware RetryHandler) Intercept(
response, err := pipeline.Next(req, middlewareIndex)
if err != nil && !IsErrTimeout(err) {
return response, clues.Stack(err).WithClues(ctx).With(ErrData(err)...)
return response, Stack(ctx, err)
}
exponentialBackOff := backoff.NewExponentialBackOff()
@ -361,7 +360,7 @@ func (middleware RetryHandler) Intercept(
exponentialBackOff,
err)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(ErrData(err)...)
return nil, Stack(ctx, err)
}
return response, nil

View File

@ -280,14 +280,12 @@ func getResources(
response, err := query(ctx, gs)
if err != nil {
return nil, clues.Wrap(err, "retrieving tenant's resources").
WithClues(ctx).
With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "retrieving tenant's resources")
}
iter, err := msgraphgocore.NewPageIterator(response, gs.Adapter(), parser)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
el := errs.Local()
@ -314,7 +312,7 @@ func getResources(
}
if err := iter.Iterate(ctx, callbackFunc); err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
return resources, el.Failure()

View File

@ -5,15 +5,14 @@ import (
"testing"
"time"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"golang.org/x/exp/maps"
"github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/connector/mockconnector"
"github.com/alcionai/corso/src/internal/connector/support"
"github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/version"
@ -325,19 +324,15 @@ func mustGetDefaultDriveID(
//revive:enable:context-as-argument
d, err := service.Client().UsersById(userID).Drive().Get(ctx, nil)
if err != nil {
err = errors.Wrapf(
err,
"failed to retrieve default user drive. user: %s, details: %s",
userID,
support.ConnectorStackErrorTrace(err),
)
err = graph.Wrap(ctx, err, "retrieving drive")
}
require.NoError(t, err)
require.NotNil(t, d.GetId())
require.NotEmpty(t, *d.GetId())
return *d.GetId()
id := ptr.Val(d.GetId())
require.NotEmpty(t, id)
return id
}
func getCollectionsAndExpected(

View File

@ -69,7 +69,7 @@ func (p *driveItemPager) GetPage(ctx context.Context) (api.DeltaPageLinker, erro
resp, err = p.builder.Get(ctx, p.options)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
return resp, nil
@ -120,8 +120,11 @@ func (p *userDrivePager) GetPage(ctx context.Context) (api.PageLinker, error) {
)
resp, err = p.builder.Get(ctx, p.options)
if err != nil {
return nil, graph.Stack(ctx, err)
}
return resp, err
return resp, nil
}
func (p *userDrivePager) SetNext(link string) {
@ -171,7 +174,7 @@ func (p *siteDrivePager) GetPage(ctx context.Context) (api.PageLinker, error) {
resp, err = p.builder.Get(ctx, p.options)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
return resp, nil
@ -194,7 +197,7 @@ func (p *siteDrivePager) GetDriveIDByName(ctx context.Context, driveName string)
for {
resp, err := p.builder.Get(ctx, p.options)
if err != nil {
return empty, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return empty, graph.Stack(ctx, err)
}
for _, entry := range resp.GetValue() {
@ -230,7 +233,7 @@ func (p *siteDrivePager) GetFolderIDByName(ctx context.Context, driveID, folderN
for {
resp, err := builder.Get(ctx, option)
if err != nil {
return empty, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return empty, graph.Stack(ctx, err)
}
for _, entry := range resp.GetValue() {

View File

@ -88,6 +88,7 @@ type Collection struct {
// itemReadFunc returns a reader for the specified item
type itemReaderFunc func(
ctx context.Context,
hc *http.Client,
item models.DriveItemable,
) (details.ItemInfo, io.ReadCloser, error)
@ -395,7 +396,7 @@ func (oc *Collection) populateItems(ctx context.Context, errs *fault.Bus) {
err error
)
_, itemData, err = oc.itemReader(oc.itemClient, item)
_, itemData, err = oc.itemReader(ctx, oc.itemClient, item)
if err != nil && graph.IsErrUnauthorized(err) {
// assume unauthorized requests are a sign of an expired

View File

@ -94,7 +94,7 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
numInstances: 1,
source: OneDriveSource,
itemDeets: nst{testItemName, 42, now},
itemReader: func(*http.Client, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
itemReader: func(context.Context, *http.Client, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
return details.ItemInfo{OneDrive: &details.OneDriveInfo{ItemName: testItemName, Modified: now}},
io.NopCloser(bytes.NewReader(testItemData)),
nil
@ -109,7 +109,7 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
numInstances: 3,
source: OneDriveSource,
itemDeets: nst{testItemName, 42, now},
itemReader: func(*http.Client, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
itemReader: func(context.Context, *http.Client, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
return details.ItemInfo{OneDrive: &details.OneDriveInfo{ItemName: testItemName, Modified: now}},
io.NopCloser(bytes.NewReader(testItemData)),
nil
@ -124,7 +124,7 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
numInstances: 1,
source: SharePointSource,
itemDeets: nst{testItemName, 42, now},
itemReader: func(*http.Client, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
itemReader: func(context.Context, *http.Client, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
return details.ItemInfo{SharePoint: &details.SharePointInfo{ItemName: testItemName, Modified: now}},
io.NopCloser(bytes.NewReader(testItemData)),
nil
@ -139,7 +139,7 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
numInstances: 3,
source: SharePointSource,
itemDeets: nst{testItemName, 42, now},
itemReader: func(*http.Client, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
itemReader: func(context.Context, *http.Client, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
return details.ItemInfo{SharePoint: &details.SharePointInfo{ItemName: testItemName, Modified: now}},
io.NopCloser(bytes.NewReader(testItemData)),
nil
@ -326,7 +326,11 @@ func (suite *CollectionUnitTestSuite) TestCollectionReadError() {
mockItem.SetLastModifiedDateTime(&now)
coll.Add(mockItem)
coll.itemReader = func(*http.Client, models.DriveItemable) (details.ItemInfo, io.ReadCloser, error) {
coll.itemReader = func(
context.Context,
*http.Client,
models.DriveItemable,
) (details.ItemInfo, io.ReadCloser, error) {
return details.ItemInfo{}, nil, assert.AnError
}
@ -407,6 +411,7 @@ func (suite *CollectionUnitTestSuite) TestCollectionPermissionBackupLatestModTim
coll.Add(mockItem)
coll.itemReader = func(
context.Context,
*http.Client,
models.DriveItemable,
) (details.ItemInfo, io.ReadCloser, error) {

View File

@ -267,7 +267,7 @@ func (c *Collections) Get(
// Enumerate drives for the specified resourceOwner
pager, err := c.drivePagerFunc(c.source, c.service, c.resourceOwner, nil)
if err != nil {
return nil, nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, graph.Stack(ctx, err)
}
retry := c.source == OneDriveSource

View File

@ -16,7 +16,6 @@ import (
"github.com/alcionai/corso/src/internal/connector/graph"
gapi "github.com/alcionai/corso/src/internal/connector/graph/api"
"github.com/alcionai/corso/src/internal/connector/onedrive/api"
"github.com/alcionai/corso/src/internal/connector/support"
"github.com/alcionai/corso/src/pkg/fault"
"github.com/alcionai/corso/src/pkg/logger"
)
@ -28,15 +27,10 @@ const (
// nextLinkKey is used to find the next link in a paged
// graph response
nextLinkKey = "@odata.nextLink"
itemChildrenRawURLFmt = "https://graph.microsoft.com/v1.0/drives/%s/items/%s/children"
itemByPathRawURLFmt = "https://graph.microsoft.com/v1.0/drives/%s/items/%s:/%s"
itemNotFoundErrorCode = "itemNotFound"
userMysiteURLNotFound = "BadRequest Unable to retrieve user's mysite URL"
userMysiteURLNotFoundMsg = "Unable to retrieve user's mysite URL"
userMysiteNotFound = "ResourceNotFound User's mysite not found"
userMysiteNotFoundMsg = "User's mysite not found"
contextDeadlineExceeded = "context deadline exceeded"
nextLinkKey = "@odata.nextLink"
itemChildrenRawURLFmt = "https://graph.microsoft.com/v1.0/drives/%s/items/%s/children"
itemByPathRawURLFmt = "https://graph.microsoft.com/v1.0/drives/%s/items/%s:/%s"
itemNotFoundErrorCode = "itemNotFound"
)
// DeltaUpdate holds the results of a current delta token. It normally
@ -97,22 +91,17 @@ func drives(
for i := 0; i <= numberOfRetries; i++ {
page, err = pager.GetPage(ctx)
if err != nil {
// Various error handling. May return an error or perform a retry.
errMsg := support.ConnectorStackErrorTraceWrap(err, "").Error()
if strings.Contains(errMsg, userMysiteURLNotFound) ||
strings.Contains(errMsg, userMysiteURLNotFoundMsg) ||
strings.Contains(errMsg, userMysiteNotFound) ||
strings.Contains(errMsg, userMysiteNotFoundMsg) {
if clues.HasLabel(err, graph.Labels.MysiteNotFound) {
logger.Ctx(ctx).Infof("resource owner does not have a drive")
return make([]models.Driveable, 0), nil // no license or drives.
}
if strings.Contains(errMsg, contextDeadlineExceeded) && i < numberOfRetries {
if graph.IsErrTimeout(err) && i < numberOfRetries {
time.Sleep(time.Duration(3*(i+1)) * time.Second)
continue
}
return nil, clues.Wrap(err, "retrieving drives").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "retrieving drives")
}
// No error encountered, break the retry loop so we can extract results
@ -122,7 +111,7 @@ func drives(
tmp, err := pager.ValuesIn(page)
if err != nil {
return nil, clues.Wrap(err, "extracting drives from response").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "extracting drives from response")
}
drives = append(drives, tmp...)
@ -232,14 +221,12 @@ func collectItems(
}
if err != nil {
return DeltaUpdate{}, nil, nil, clues.Wrap(err, "getting page").WithClues(ctx).With(graph.ErrData(err)...)
return DeltaUpdate{}, nil, nil, graph.Wrap(ctx, err, "getting page")
}
vals, err := pager.ValuesIn(page)
if err != nil {
return DeltaUpdate{}, nil, nil, clues.Wrap(err, "extracting items from response").
WithClues(ctx).
With(graph.ErrData(err)...)
return DeltaUpdate{}, nil, nil, graph.Wrap(ctx, err, "extracting items from response")
}
err = collector(
@ -297,15 +284,15 @@ func getFolder(
foundItem, err = builder.Get(ctx, nil)
if err != nil {
if graph.IsErrDeletedInFlight(err) {
return nil, clues.Stack(errFolderNotFound, err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, clues.Stack(errFolderNotFound, err))
}
return nil, clues.Wrap(err, "getting folder").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting folder")
}
// Check if the item found is a folder, fail the call if not
if foundItem.GetFolder() == nil {
return nil, clues.Stack(errFolderNotFound).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, errFolderNotFound)
}
return foundItem, nil
@ -325,7 +312,7 @@ func createItem(
newItem, err := builder.Post(ctx, newItem, nil)
if err != nil {
return nil, clues.Wrap(err, "creating item").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "creating item")
}
return newItem, nil
@ -447,10 +434,7 @@ func DeleteItem(
) error {
err := gs.Client().DrivesById(driveID).ItemsById(itemID).Delete(ctx, nil)
if err != nil {
return clues.Wrap(err, "deleting item").
WithClues(ctx).
With("item_id", itemID).
With(graph.ErrData(err)...)
return graph.Wrap(ctx, err, "deleting item").With("item_id", itemID)
}
return nil

View File

@ -12,10 +12,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/connector/graph/api"
"github.com/alcionai/corso/src/internal/connector/support"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/control"
"github.com/alcionai/corso/src/pkg/fault"
@ -78,6 +78,11 @@ func TestOneDriveUnitSuite(t *testing.T) {
suite.Run(t, &OneDriveUnitSuite{Suite: tester.NewUnitSuite(t)})
}
const (
userMysiteURLNotFound = "BadRequest Unable to retrieve user's mysite URL"
userMysiteNotFound = "ResourceNotFound User's mysite not found"
)
func odErr(code string) *odataerrors.ODataError {
odErr := &odataerrors.ODataError{}
merr := odataerrors.MainError{}
@ -88,6 +93,9 @@ func odErr(code string) *odataerrors.ODataError {
}
func (suite *OneDriveUnitSuite) TestDrives() {
ctx, flush := tester.NewContext()
defer flush()
numDriveResults := 4
emptyLink := ""
link := "foo"
@ -95,18 +103,8 @@ func (suite *OneDriveUnitSuite) TestDrives() {
// These errors won't be the "correct" format when compared to what graph
// returns, but they're close enough to have the same info when the inner
// details are extracted via support package.
mySiteURLNotFound := support.ConnectorStackErrorTraceWrap(
odErr(userMysiteURLNotFound),
"maximum retries or unretryable",
)
mySiteNotFound := support.ConnectorStackErrorTraceWrap(
odErr(userMysiteNotFound),
"maximum retries or unretryable",
)
deadlineExceeded := support.ConnectorStackErrorTraceWrap(
odErr(contextDeadlineExceeded),
"maximum retries or unretryable",
)
mySiteURLNotFound := odErr(userMysiteURLNotFound)
mySiteNotFound := odErr(userMysiteNotFound)
resultDrives := make([]models.Driveable, 0, numDriveResults)
@ -122,7 +120,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
for i := 0; i < getDrivesRetries+1; i++ {
tooManyRetries = append(tooManyRetries, pagerResult{
err: deadlineExceeded,
err: context.DeadlineExceeded,
})
}
@ -219,7 +217,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
{
drives: nil,
nextLink: nil,
err: mySiteURLNotFound,
err: graph.Stack(ctx, mySiteURLNotFound),
},
},
retry: true,
@ -232,7 +230,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
{
drives: nil,
nextLink: nil,
err: mySiteNotFound,
err: graph.Stack(ctx, mySiteNotFound),
},
},
retry: true,
@ -250,7 +248,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
{
drives: nil,
nextLink: nil,
err: deadlineExceeded,
err: context.DeadlineExceeded,
},
{
drives: resultDrives[numDriveResults/2:],
@ -273,7 +271,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
{
drives: nil,
nextLink: nil,
err: deadlineExceeded,
err: context.DeadlineExceeded,
},
{
drives: resultDrives[numDriveResults/2:],
@ -437,9 +435,6 @@ func (fm testFolderMatcher) Matches(path string) bool {
}
func (suite *OneDriveSuite) TestOneDriveNewCollections() {
ctx, flush := tester.NewContext()
defer flush()
creds, err := tester.NewM365Account(suite.T()).M365Config()
require.NoError(suite.T(), err)
@ -458,13 +453,18 @@ func (suite *OneDriveSuite) TestOneDriveNewCollections() {
for _, test := range tests {
suite.Run(test.name, func() {
t := suite.T()
ctx, flush := tester.NewContext()
defer flush()
service := loadTestService(t)
scope := selectors.
NewOneDriveBackup([]string{test.user}).
AllData()[0]
odcs, excludes, err := NewCollections(
var (
t = suite.T()
service = loadTestService(t)
scope = selectors.
NewOneDriveBackup([]string{test.user}).
AllData()[0]
)
colls := NewCollections(
graph.HTTPClient(graph.NoTimeout()),
creds.AzureTenantID,
test.user,
@ -472,9 +472,12 @@ func (suite *OneDriveSuite) TestOneDriveNewCollections() {
testFolderMatcher{scope},
service,
service.updateStatus,
control.Options{ToggleFeatures: control.Toggles{EnablePermissionsBackup: true}},
).Get(ctx, nil, fault.New(true))
assert.NoError(t, err)
control.Options{
ToggleFeatures: control.Toggles{EnablePermissionsBackup: true},
})
odcs, excludes, err := colls.Get(ctx, nil, fault.New(true))
assert.NoError(t, err, clues.InErr(err))
// Don't expect excludes as this isn't an incremental backup.
assert.Empty(t, excludes)

View File

@ -35,7 +35,7 @@ func getDriveItem(
) (models.DriveItemable, error) {
di, err := srv.Client().DrivesById(driveID).ItemsById(itemID).Get(ctx, nil)
if err != nil {
return nil, clues.Wrap(err, "getting item").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting item")
}
return di, nil
@ -46,10 +46,11 @@ func getDriveItem(
// and using a http client to initialize a reader
// TODO: Add metadata fetching to SharePoint
func sharePointItemReader(
ctx context.Context,
hc *http.Client,
item models.DriveItemable,
) (details.ItemInfo, io.ReadCloser, error) {
resp, err := downloadItem(hc, item)
resp, err := downloadItem(ctx, hc, item)
if err != nil {
return details.ItemInfo{}, nil, errors.Wrap(err, "downloading item")
}
@ -106,6 +107,7 @@ func oneDriveItemMetaReader(
// It crafts this by querying M365 for a download URL for the item
// and using a http client to initialize a reader
func oneDriveItemReader(
ctx context.Context,
hc *http.Client,
item models.DriveItemable,
) (details.ItemInfo, io.ReadCloser, error) {
@ -115,7 +117,7 @@ func oneDriveItemReader(
)
if isFile {
resp, err := downloadItem(hc, item)
resp, err := downloadItem(ctx, hc, item)
if err != nil {
return details.ItemInfo{}, nil, errors.Wrap(err, "downloading item")
}
@ -130,7 +132,7 @@ func oneDriveItemReader(
return dii, rc, nil
}
func downloadItem(hc *http.Client, item models.DriveItemable) (*http.Response, error) {
func downloadItem(ctx context.Context, hc *http.Client, item models.DriveItemable) (*http.Response, error) {
url, ok := item.GetAdditionalData()[downloadURLKey].(*string)
if !ok {
return nil, clues.New("extracting file url").With("item_id", ptr.Val(item.GetId()))
@ -138,7 +140,7 @@ func downloadItem(hc *http.Client, item models.DriveItemable) (*http.Response, e
req, err := http.NewRequest(http.MethodGet, *url, nil)
if err != nil {
return nil, clues.Wrap(err, "new request").With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "new request")
}
//nolint:lll
@ -229,12 +231,7 @@ func oneDriveItemPermissionInfo(
Permissions().
Get(ctx, nil)
if err != nil {
err = clues.Wrap(err, "fetching item permissions").
WithClues(ctx).
With("item_id", id).
With(graph.ErrData(err)...)
return nil, err
return nil, graph.Wrap(ctx, err, "getting item metadata").With("item_id", id)
}
uperms := filterUserPermissions(ctx, perm.GetValue())
@ -360,9 +357,7 @@ func driveItemWriter(
r, err := service.Client().DrivesById(driveID).ItemsById(itemID).CreateUploadSession().Post(ctx, session, nil)
if err != nil {
return nil, clues.Wrap(err, "creating item upload session").
WithClues(ctx).
With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "creating item upload session")
}
logger.Ctx(ctx).Debug("created an upload session")
@ -428,7 +423,7 @@ func fetchParentReference(
drive, err := service.Client().DrivesById(driveID).Get(ctx, options)
if err != nil {
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Stack(ctx, err)
}
orig.SetName(drive.GetName())

View File

@ -111,7 +111,7 @@ func (suite *ItemIntegrationSuite) TestItemReader_oneDrive() {
)
// Read data for the file
itemInfo, itemData, err := oneDriveItemReader(graph.HTTPClient(graph.NoTimeout()), driveItem)
itemInfo, itemData, err := oneDriveItemReader(ctx, graph.HTTPClient(graph.NoTimeout()), driveItem)
require.NoError(suite.T(), err)
require.NotNil(suite.T(), itemInfo.OneDrive)

View File

@ -190,7 +190,7 @@ func restorePermissions(
PermissionsById(permissionIDMappings[p.ID]).
Delete(ctx, nil)
if err != nil {
return clues.Wrap(err, "removing permissions").WithClues(ctx).With(graph.ErrData(err)...)
return graph.Wrap(ctx, err, "removing permissions")
}
}
@ -222,7 +222,7 @@ func restorePermissions(
np, err := service.Client().DrivesById(driveID).ItemsById(itemID).Invite().Post(ctx, pbody, nil)
if err != nil {
return clues.Wrap(err, "setting permissions").WithClues(ctx).With(graph.ErrData(err)...)
return graph.Wrap(ctx, err, "setting permissions")
}
permissionIDMappings[p.ID] = *np.GetValue()[0].GetId()

View File

@ -474,7 +474,7 @@ func CreateRestoreFolders(
) (string, error) {
driveRoot, err := service.Client().DrivesById(driveID).Root().Get(ctx, nil)
if err != nil {
return "", clues.Wrap(err, "getting drive root").WithClues(ctx).With(graph.ErrData(err)...)
return "", graph.Wrap(ctx, err, "getting drive root")
}
parentFolderID := ptr.Val(driveRoot.GetId())
@ -550,7 +550,7 @@ func restoreData(
// Upload the stream data
written, err := io.CopyBuffer(w, progReader, copyBuffer)
if err != nil {
return "", details.ItemInfo{}, clues.Wrap(err, "writing item bytes").WithClues(ctx).With(graph.ErrData(err)...)
return "", details.ItemInfo{}, graph.Wrap(ctx, err, "writing item bytes")
}
dii := details.ItemInfo{}

View File

@ -70,7 +70,7 @@ func GetSitePages(
page, err = serv.Client().SitesById(siteID).PagesById(pageID).Get(ctx, opts)
if err != nil {
el.AddRecoverable(clues.Wrap(err, "fetching page").WithClues(ctx).With(graph.ErrData(err)...))
el.AddRecoverable(graph.Wrap(ctx, err, "fetching page"))
return
}
@ -113,7 +113,7 @@ func FetchPages(ctx context.Context, bs *discover.BetaService, siteID string) ([
for {
resp, err = builder.Get(ctx, opts)
if err != nil {
return nil, clues.Wrap(err, "fetching site page").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "fetching site page")
}
for _, entry := range resp.GetValue() {
@ -162,7 +162,7 @@ func DeleteSitePage(
) error {
err := serv.Client().SitesById(siteID).PagesById(pageID).Delete(ctx, nil)
if err != nil {
return clues.Wrap(err, "deleting page").WithClues(ctx).With(graph.ErrData(err)...)
return graph.Wrap(ctx, err, "deleting page")
}
return nil
@ -222,7 +222,7 @@ func RestoreSitePage(
// See: https://learn.microsoft.com/en-us/graph/api/sitepage-create?view=graph-rest-beta
restoredPage, err := service.Client().SitesById(siteID).Pages().Post(ctx, page, nil)
if err != nil {
return dii, clues.Wrap(err, "creating page").WithClues(ctx).With(graph.ErrData(err)...)
return dii, graph.Wrap(ctx, err, "creating page")
}
pageID = ptr.Val(restoredPage.GetId())
@ -240,7 +240,7 @@ func RestoreSitePage(
Publish().
Post(ctx, nil)
if err != nil {
return dii, clues.Wrap(err, "publishing page").WithClues(ctx).With(graph.ErrData(err)...)
return dii, graph.Wrap(ctx, err, "publishing page")
}
dii.SharePoint = PageInfo(restoredPage, int64(len(byteArray)))

View File

@ -231,7 +231,7 @@ func (sc *Collection) retrieveLists(
break
}
byteArray, err := serializeContent(wtr, lst)
byteArray, err := serializeContent(ctx, wtr, lst)
if err != nil {
el.AddRecoverable(clues.Wrap(err, "serializing list").WithClues(ctx).Label(fault.LabelForceNoBackupCreation))
continue
@ -299,7 +299,7 @@ func (sc *Collection) retrievePages(
break
}
byteArray, err := serializeContent(wtr, pg)
byteArray, err := serializeContent(ctx, wtr, pg)
if err != nil {
el.AddRecoverable(clues.Wrap(err, "serializing page").WithClues(ctx).Label(fault.LabelForceNoBackupCreation))
continue
@ -324,17 +324,21 @@ func (sc *Collection) retrievePages(
return metrics, el.Failure()
}
func serializeContent(writer *kw.JsonSerializationWriter, obj absser.Parsable) ([]byte, error) {
func serializeContent(
ctx context.Context,
writer *kw.JsonSerializationWriter,
obj absser.Parsable,
) ([]byte, error) {
defer writer.Close()
err := writer.WriteObjectValue("", obj)
if err != nil {
return nil, clues.Wrap(err, "writing object").With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "writing object")
}
byteArray, err := writer.GetSerializedContent()
if err != nil {
return nil, clues.Wrap(err, "getting content from writer").With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting content from writer")
}
return byteArray, nil

View File

@ -206,7 +206,7 @@ func (suite *SharePointCollectionSuite) TestListCollection_Restore() {
for {
resp, err := builder.Get(ctx, nil)
assert.NoError(t, err, "experienced query error during clean up. Details: "+support.ConnectorStackErrorTrace(err))
assert.NoError(t, err, "getting site lists")
for _, temp := range resp.GetValue() {
if *temp.GetDisplayName() == deets.SharePoint.ItemName {

View File

@ -191,7 +191,7 @@ func collectLibraries(
// token-based incrementals.
odcs, excludes, err := colls.Get(ctx, nil, errs)
if err != nil {
return nil, nil, clues.Wrap(err, "getting library").WithClues(ctx).With(graph.ErrData(err)...)
return nil, nil, graph.Wrap(ctx, err, "getting library")
}
return append(collections, odcs...), excludes, nil

View File

@ -7,11 +7,9 @@ import (
"github.com/alcionai/clues"
"github.com/microsoftgraph/msgraph-sdk-go/models"
mssite "github.com/microsoftgraph/msgraph-sdk-go/sites"
"github.com/pkg/errors"
"github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/connector/graph"
"github.com/alcionai/corso/src/internal/connector/support"
"github.com/alcionai/corso/src/pkg/fault"
)
@ -46,7 +44,7 @@ func preFetchLists(
for {
resp, err := builder.Get(ctx, options)
if err != nil {
return nil, clues.Wrap(err, "getting lists").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting lists")
}
for _, entry := range resp.GetValue() {
@ -131,7 +129,7 @@ func loadSiteLists(
entry, err = gs.Client().SitesById(siteID).ListsById(id).Get(ctx, nil)
if err != nil {
el.AddRecoverable(clues.Wrap(err, "getting site list").WithClues(ctx).With(graph.ErrData(err)...))
el.AddRecoverable(graph.Wrap(ctx, err, "getting site list"))
return
}
@ -209,7 +207,7 @@ func fetchListItems(
resp, err := builder.Get(ctx, nil)
if err != nil {
return nil, errors.Wrap(err, support.ConnectorStackErrorTrace(err))
return nil, err
}
for _, itm := range resp.GetValue() {
@ -221,7 +219,7 @@ func fetchListItems(
fields, err := newPrefix.Fields().Get(ctx, nil)
if err != nil {
el.AddRecoverable(clues.Wrap(err, "getting list fields").WithClues(ctx).With(graph.ErrData(err)...))
el.AddRecoverable(graph.Wrap(ctx, err, "getting list fields"))
continue
}
@ -257,7 +255,7 @@ func fetchColumns(
for {
resp, err := builder.Get(ctx, nil)
if err != nil {
return nil, clues.Wrap(err, "getting list columns").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting list columns")
}
cs = append(cs, resp.GetValue()...)
@ -274,7 +272,7 @@ func fetchColumns(
for {
resp, err := builder.Get(ctx, nil)
if err != nil {
return nil, clues.Wrap(err, "getting content columns").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting content columns")
}
cs = append(cs, resp.GetValue()...)
@ -315,7 +313,7 @@ func fetchContentTypes(
resp, err := builder.Get(ctx, nil)
if err != nil {
return nil, errors.Wrap(err, support.ConnectorStackErrorTrace(err))
return nil, err
}
for _, cont := range resp.GetValue() {
@ -367,7 +365,7 @@ func fetchColumnLinks(
for {
resp, err := builder.Get(ctx, nil)
if err != nil {
return nil, clues.Wrap(err, "getting column links").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting column links")
}
links = append(links, resp.GetValue()...)
@ -394,7 +392,7 @@ func DeleteList(
) error {
err := gs.Client().SitesById(siteID).ListsById(listID).Delete(ctx, nil)
if err != nil {
return clues.Wrap(err, "deleting list").WithClues(ctx).With(graph.ErrData(err)...)
return graph.Wrap(ctx, err, "deleting list")
}
return nil

View File

@ -6,7 +6,6 @@ import (
absser "github.com/microsoft/kiota-abstractions-go/serialization"
mssite "github.com/microsoftgraph/msgraph-sdk-go/sites"
"github.com/alcionai/clues"
"github.com/alcionai/corso/src/internal/connector/graph"
)
@ -22,7 +21,7 @@ func GetAllSitesForTenant(ctx context.Context, gs graph.Servicer) (absser.Parsab
sites, err := gs.Client().Sites().Get(ctx, options)
if err != nil {
return nil, clues.Wrap(err, "getting sites").WithClues(ctx).With(graph.ErrData(err)...)
return nil, graph.Wrap(ctx, err, "getting sites")
}
return sites, nil

View File

@ -126,7 +126,7 @@ func createRestoreFolders(
// Get Main Drive for Site, Documents
mainDrive, err := service.Client().SitesById(siteID).Drive().Get(ctx, nil)
if err != nil {
return "", clues.Wrap(err, "getting site drive root").WithClues(ctx).With(graph.ErrData(err)...)
return "", graph.Wrap(ctx, err, "getting site drive root")
}
return onedrive.CreateRestoreFolders(ctx, service, *mainDrive.GetId(), restoreFolders)
@ -182,7 +182,7 @@ func restoreListItem(
// Restore to List base to M365 back store
restoredList, err := service.Client().SitesById(siteID).Lists().Post(ctx, newList, nil)
if err != nil {
return dii, clues.Wrap(err, "restoring list").WithClues(ctx).With(graph.ErrData(err)...)
return dii, graph.Wrap(ctx, err, "restoring list")
}
// Uploading of ListItems is conducted after the List is restored
@ -195,10 +195,8 @@ func restoreListItem(
Items().
Post(ctx, lItem, nil)
if err != nil {
return dii, clues.Wrap(err, "restoring list items").
With("restored_list_id", ptr.Val(restoredList.GetId())).
WithClues(ctx).
With(graph.ErrData(err)...)
return dii, graph.Wrap(ctx, err, "restoring list items").
With("restored_list_id", ptr.Val(restoredList.GetId()))
}
}
}

View File

@ -1,130 +0,0 @@
package support
import (
"fmt"
"strconv"
"strings"
multierror "github.com/hashicorp/go-multierror"
msgraph_errors "github.com/microsoftgraph/msgraph-sdk-go/models/odataerrors"
"github.com/pkg/errors"
)
// WrapErrorAndAppend helper function used to attach identifying information to an error
// and return it as a mulitierror
func WrapAndAppend(identifier string, e, previous error) error {
return multierror.Append(previous, errors.Wrap(e, identifier))
}
// WrapErrorAndAppendf format version of WrapErrorAndAppend
func WrapAndAppendf(identifier interface{}, e, previous error) error {
return multierror.Append(previous, errors.Wrapf(e, "%v", identifier))
}
// GetErrors Helper method to return the integer amount of errors in multi error
func GetNumberOfErrors(err error) int {
if err == nil {
return 0
}
result, _, wasFound := strings.Cut(err.Error(), " ")
if wasFound {
aNum, err := strconv.Atoi(result)
if err == nil {
return aNum
}
}
return 1
}
// ListErrors is a helper method used to return the string of errors when
// the multiError library is used.
// depends on ConnectorStackErrorTrace
func ListErrors(multi multierror.Error) string {
aString := ""
for idx, err := range multi.Errors {
detail := ConnectorStackErrorTrace(err)
if detail == "" {
detail = fmt.Sprintf("%v", err)
}
aString = aString + fmt.Sprintf("\n\tErr: %d %v", idx+1, detail)
}
return aString
}
// concatenateStringFromPointers is a helper function that adds
// strings to the originalMessage iff the pointer is not nil
func concatenateStringFromPointers(orig string, pointers []*string) string {
for _, pointer := range pointers {
if pointer != nil {
orig = strings.Join([]string{orig, *pointer}, " ")
}
}
return orig
}
// ConnectorStackErrorTraceWrap is a helper function that wraps the
// stack trace for oDataErrors (if the error has one) onto the prefix.
// If no stack trace is found, wraps the error with only the prefix.
func ConnectorStackErrorTraceWrap(e error, prefix string) error {
cset := ConnectorStackErrorTrace(e)
if len(cset) > 0 {
return errors.Wrap(e, prefix+": "+cset)
}
return errors.Wrap(e, prefix)
}
// ConnectorStackErrorTrace is a helper function that extracts
// the stack trace for oDataErrors, if the error has one.
func ConnectorStackErrorTrace(e error) string {
eMessage := ""
if oDataError, ok := e.(msgraph_errors.ODataErrorable); ok {
// Get MainError
mainErr := oDataError.GetError()
// message *string
// target *string
// code *string
// details ErrorDetailsable
// Ignoring Additional Detail
code := mainErr.GetCode()
subject := mainErr.GetMessage()
target := mainErr.GetTarget()
details := mainErr.GetDetails()
inners := mainErr.GetInnererror()
eMessage = concatenateStringFromPointers(eMessage,
[]*string{code, subject, target})
// Get Error Details
// code, message, target
if details != nil {
eMessage = eMessage + "\nDetails Section:"
for idx, detail := range details {
dMessage := fmt.Sprintf("Detail %d:", idx)
c := detail.GetCode()
m := detail.GetMessage()
t := detail.GetTarget()
dMessage = concatenateStringFromPointers(dMessage,
[]*string{c, m, t})
eMessage = eMessage + dMessage
}
}
if inners != nil {
eMessage = eMessage + "\nConnector Section:"
client := inners.GetClientRequestId()
rID := inners.GetRequestId()
eMessage = concatenateStringFromPointers(eMessage,
[]*string{client, rID})
}
}
return eMessage
}

View File

@ -1,110 +0,0 @@
package support
import (
"errors"
"fmt"
"strings"
"testing"
multierror "github.com/hashicorp/go-multierror"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/tester"
)
type GraphConnectorErrorSuite struct {
tester.Suite
}
func TestGraphConnectorErrorSuite(t *testing.T) {
suite.Run(t, &GraphConnectorErrorSuite{Suite: tester.NewUnitSuite(t)})
}
func (suite *GraphConnectorErrorSuite) TestWrapAndAppend() {
t := suite.T()
err1 := fmt.Errorf("New Error")
err2 := errors.New("I have two")
returnErr := WrapAndAppend("arc376", err2, err1)
assert.True(t, strings.Contains(returnErr.Error(), "arc376"))
assert.Error(t, returnErr)
multi := &multierror.Error{Errors: []error{err1, err2}}
assert.True(t, strings.Contains(ListErrors(*multi), "two")) // Does not contain the wrapped information
t.Log(ListErrors(*multi))
}
func (suite *GraphConnectorErrorSuite) TestWrapAndAppend_OnVar() {
var (
err1 error
id = "xi2058"
)
received := WrapAndAppend(id, errors.New("network error"), err1)
assert.True(suite.T(), strings.Contains(received.Error(), id))
}
func (suite *GraphConnectorErrorSuite) TestWrapAndAppend_Add3() {
t := suite.T()
errOneTwo := WrapAndAppend("user1", assert.AnError, assert.AnError)
combined := WrapAndAppend("unix36", assert.AnError, errOneTwo)
allErrors := WrapAndAppend("fxi92874", assert.AnError, combined)
assert.True(t, strings.Contains(combined.Error(), "unix36"))
assert.True(t, strings.Contains(combined.Error(), "user1"))
assert.True(t, strings.Contains(allErrors.Error(), "fxi92874"))
}
func (suite *GraphConnectorErrorSuite) TestWrapAndAppendf() {
err1 := assert.AnError
err2 := assert.AnError
combined := WrapAndAppendf(134323, err2, err1)
assert.True(suite.T(), strings.Contains(combined.Error(), "134323"))
}
func (suite *GraphConnectorErrorSuite) TestConcatenateStringFromPointers() {
var (
outString string
v1 = "Corso"
v3 = "remains"
s1 = &v1
s2 *string
s3 = &v3
t = suite.T()
)
outString = concatenateStringFromPointers(outString, []*string{s1, s2, s3})
assert.True(t, strings.Contains(outString, v1))
assert.True(t, strings.Contains(outString, v3))
}
func (suite *GraphConnectorErrorSuite) TestGetNumberOfErrors() {
table := []struct {
name string
errs error
expected int
}{
{
name: "No error",
errs: nil,
expected: 0,
},
{
name: "Not an ErrorList",
errs: errors.New("network error"),
expected: 1,
},
{
name: "Three Errors",
errs: WrapAndAppend("tres", errors.New("three"), WrapAndAppend("arc376", errors.New("one"), errors.New("two"))),
expected: 3,
},
}
for _, test := range table {
suite.Run(test.name, func() {
result := GetNumberOfErrors(test.errs)
assert.Equal(suite.T(), result, test.expected)
})
}
}

View File

@ -1006,7 +1006,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchangeIncrementals() {
require.NotEmpty(t, ids, "message ids in folder")
err = cli.MessagesById(ids[0]).Delete(ctx, nil)
require.NoError(t, err, "deleting email item: %s", support.ConnectorStackErrorTrace(err))
require.NoError(t, err, "deleting email item")
case path.ContactsCategory:
ids, _, _, err := ac.Contacts().GetAddedAndRemovedItemIDs(ctx, suite.user, containerID, "")
@ -1014,7 +1014,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchangeIncrementals() {
require.NotEmpty(t, ids, "contact ids in folder")
err = cli.ContactsById(ids[0]).Delete(ctx, nil)
require.NoError(t, err, "deleting contact item: %s", support.ConnectorStackErrorTrace(err))
require.NoError(t, err, "deleting contact item")
case path.EventsCategory:
ids, _, _, err := ac.Events().GetAddedAndRemovedItemIDs(ctx, suite.user, containerID, "")
@ -1022,7 +1022,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchangeIncrementals() {
require.NotEmpty(t, ids, "event ids in folder")
err = cli.CalendarsById(ids[0]).Delete(ctx, nil)
require.NoError(t, err, "deleting calendar: %s", support.ConnectorStackErrorTrace(err))
require.NoError(t, err, "deleting calendar")
}
}
},

View File

@ -7,7 +7,6 @@ import (
"github.com/alcionai/corso/src/cli/print"
"github.com/alcionai/corso/src/internal/common"
"github.com/alcionai/corso/src/internal/connector/support"
"github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/internal/stats"
"github.com/alcionai/corso/src/internal/version"
@ -158,23 +157,13 @@ func (b Backup) Values() []string {
}
func (b Backup) countErrors() int {
errCount := b.ErrorCount
if errCount > 0 {
return errCount
if b.ErrorCount > 0 {
return b.ErrorCount
}
// current tracking
if b.ReadErrors != nil || b.WriteErrors != nil {
return support.GetNumberOfErrors(b.ReadErrors) + support.GetNumberOfErrors(b.WriteErrors)
}
// future tracking
if b.Errors.Failure != nil || len(b.Errors.Recovered) > 0 {
if b.Errors.Failure != nil {
errCount++
}
errCount += len(b.Errors.Recovered)
errCount := len(b.Errors.Recovered)
if b.Errors.Failure != nil {
errCount++
}
return errCount