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:
parent
30d9705829
commit
1ca49c53a9
@ -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))
|
resp, err = service.Client().Users().Get(ctx, userOptions(&userFilterNoGuests))
|
||||||
|
|
||||||
if err != nil {
|
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(
|
iter, err := msgraphgocore.NewPageIterator(
|
||||||
@ -105,7 +105,7 @@ func (c Users) GetAll(ctx context.Context, errs *fault.Bus) ([]models.Userable,
|
|||||||
service.Adapter(),
|
service.Adapter(),
|
||||||
models.CreateUserCollectionResponseFromDiscriminatorValue)
|
models.CreateUserCollectionResponseFromDiscriminatorValue)
|
||||||
if err != nil {
|
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 (
|
var (
|
||||||
@ -120,7 +120,7 @@ func (c Users) GetAll(ctx context.Context, errs *fault.Bus) ([]models.Userable,
|
|||||||
|
|
||||||
u, err := validateUser(item)
|
u, err := validateUser(item)
|
||||||
if err != nil {
|
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 {
|
} else {
|
||||||
us = append(us, u)
|
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 {
|
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()
|
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)
|
resp, err = c.stable.Client().UsersById(userID).Get(ctx, nil)
|
||||||
|
|
||||||
if err != 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
|
return resp, err
|
||||||
@ -163,7 +163,7 @@ func (c Users) GetInfo(ctx context.Context, userID string) (*UserInfo, error) {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !graph.IsErrExchangeMailFolderNotFound(err) {
|
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)
|
delete(userInfo.DiscoveredServices, path.ExchangeService)
|
||||||
|
|||||||
@ -49,7 +49,7 @@ func (c Contacts) CreateContactFolder(
|
|||||||
|
|
||||||
mdl, err := c.stable.Client().UsersById(user).ContactFolders().Post(ctx, requestBody, nil)
|
mdl, err := c.stable.Client().UsersById(user).ContactFolders().Post(ctx, requestBody, nil)
|
||||||
if err != 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
|
return mdl, nil
|
||||||
@ -62,7 +62,7 @@ func (c Contacts) DeleteContainer(
|
|||||||
) error {
|
) error {
|
||||||
err := c.stable.Client().UsersById(user).ContactFoldersById(folderID).Delete(ctx, nil)
|
err := c.stable.Client().UsersById(user).ContactFoldersById(folderID).Delete(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -76,7 +76,7 @@ func (c Contacts) GetItem(
|
|||||||
) (serialization.Parsable, *details.ExchangeInfo, error) {
|
) (serialization.Parsable, *details.ExchangeInfo, error) {
|
||||||
cont, err := c.stable.Client().UsersById(user).ContactsById(itemID).Get(ctx, nil)
|
cont, err := c.stable.Client().UsersById(user).ContactsById(itemID).Get(ctx, nil)
|
||||||
if err != 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
|
return cont, ContactInfo(cont), nil
|
||||||
@ -88,12 +88,12 @@ func (c Contacts) GetContainerByID(
|
|||||||
) (graph.Container, error) {
|
) (graph.Container, error) {
|
||||||
ofcf, err := optionsForContactFolderByID([]string{"displayName", "parentFolderId"})
|
ofcf, err := optionsForContactFolderByID([]string{"displayName", "parentFolderId"})
|
||||||
if err != nil {
|
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)
|
resp, err := c.stable.Client().UsersById(userID).ContactFoldersById(dirID).Get(ctx, ofcf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -112,17 +112,14 @@ func (c Contacts) EnumerateContainers(
|
|||||||
) error {
|
) error {
|
||||||
service, err := c.service()
|
service, err := c.service()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fields := []string{"displayName", "parentFolderId"}
|
fields := []string{"displayName", "parentFolderId"}
|
||||||
|
|
||||||
ofcf, err := optionsForContactChildFolders(fields)
|
ofcf, err := optionsForContactChildFolders(fields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Wrap(err, "setting contact child folder options").
|
return graph.Wrap(ctx, err, "setting contact child folder options")
|
||||||
WithClues(ctx).
|
|
||||||
With(graph.ErrData(err)...).
|
|
||||||
With("options_fields", fields)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
el := errs.Local()
|
el := errs.Local()
|
||||||
@ -138,7 +135,7 @@ func (c Contacts) EnumerateContainers(
|
|||||||
|
|
||||||
resp, err := builder.Get(ctx, ofcf)
|
resp, err := builder.Get(ctx, ofcf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fold := range resp.GetValue() {
|
for _, fold := range resp.GetValue() {
|
||||||
@ -147,11 +144,7 @@ func (c Contacts) EnumerateContainers(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := checkIDAndName(fold); err != nil {
|
if err := checkIDAndName(fold); err != nil {
|
||||||
el.AddRecoverable(clues.Stack(err).
|
errs.AddRecoverable(graph.Stack(ctx, err).Label(fault.LabelForceNoBackupCreation))
|
||||||
WithClues(ctx).
|
|
||||||
With(graph.ErrData(err)...).
|
|
||||||
Label(fault.LabelForceNoBackupCreation))
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,11 +155,7 @@ func (c Contacts) EnumerateContainers(
|
|||||||
|
|
||||||
temp := graph.NewCacheFolder(fold, nil, nil)
|
temp := graph.NewCacheFolder(fold, nil, nil)
|
||||||
if err := fn(temp); err != nil {
|
if err := fn(temp); err != nil {
|
||||||
el.AddRecoverable(clues.Stack(err).
|
errs.AddRecoverable(graph.Stack(fctx, err).Label(fault.LabelForceNoBackupCreation))
|
||||||
WithClues(fctx).
|
|
||||||
With(graph.ErrData(err)...).
|
|
||||||
Label(fault.LabelForceNoBackupCreation))
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,7 +186,7 @@ type contactPager struct {
|
|||||||
func (p *contactPager) getPage(ctx context.Context) (api.DeltaPageLinker, error) {
|
func (p *contactPager) getPage(ctx context.Context) (api.DeltaPageLinker, error) {
|
||||||
resp, err := p.builder.Get(ctx, p.options)
|
resp, err := p.builder.Get(ctx, p.options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -217,7 +206,7 @@ func (c Contacts) GetAddedAndRemovedItemIDs(
|
|||||||
) ([]string, []string, DeltaUpdate, error) {
|
) ([]string, []string, DeltaUpdate, error) {
|
||||||
service, err := c.service()
|
service, err := c.service()
|
||||||
if err != nil {
|
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
|
var resetDelta bool
|
||||||
@ -232,7 +221,7 @@ func (c Contacts) GetAddedAndRemovedItemIDs(
|
|||||||
return nil,
|
return nil,
|
||||||
nil,
|
nil,
|
||||||
DeltaUpdate{},
|
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 {
|
if len(oldDelta) > 0 {
|
||||||
@ -250,7 +239,7 @@ func (c Contacts) GetAddedAndRemovedItemIDs(
|
|||||||
// only return on error if it is NOT a delta issue.
|
// only return on error if it is NOT a delta issue.
|
||||||
// on bad deltas we retry the call with the regular builder
|
// on bad deltas we retry the call with the regular builder
|
||||||
if !graph.IsErrInvalidDelta(err) {
|
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
|
resetDelta = true
|
||||||
@ -303,12 +292,12 @@ func (c Contacts) Serialize(
|
|||||||
defer writer.Close()
|
defer writer.Close()
|
||||||
|
|
||||||
if err = writer.WriteObjectValue("", contact); err != nil {
|
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()
|
bs, err := writer.GetSerializedContent()
|
||||||
if err != nil {
|
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
|
return bs, nil
|
||||||
|
|||||||
@ -50,7 +50,7 @@ func (c Events) CreateCalendar(
|
|||||||
|
|
||||||
mdl, err := c.stable.Client().UsersById(user).Calendars().Post(ctx, requestbody, nil)
|
mdl, err := c.stable.Client().UsersById(user).Calendars().Post(ctx, requestbody, nil)
|
||||||
if err != 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
|
return mdl, nil
|
||||||
@ -64,7 +64,7 @@ func (c Events) DeleteContainer(
|
|||||||
) error {
|
) error {
|
||||||
err := c.stable.Client().UsersById(user).CalendarsById(calendarID).Delete(ctx, nil)
|
err := c.stable.Client().UsersById(user).CalendarsById(calendarID).Delete(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -76,17 +76,17 @@ func (c Events) GetContainerByID(
|
|||||||
) (graph.Container, error) {
|
) (graph.Container, error) {
|
||||||
service, err := c.service()
|
service, err := c.service()
|
||||||
if err != nil {
|
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"})
|
ofc, err := optionsForCalendarsByID([]string{"name", "owner"})
|
||||||
if err != nil {
|
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)
|
cal, err := service.Client().UsersById(userID).CalendarsById(containerID).Get(ctx, ofc)
|
||||||
if err != nil {
|
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
|
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)
|
event, err = c.stable.Client().UsersById(user).EventsById(itemID).Get(ctx, nil)
|
||||||
if err != 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()) {
|
if *event.GetHasAttachments() || HasAttachments(event.GetBody()) {
|
||||||
@ -122,7 +122,7 @@ func (c Events) GetItem(
|
|||||||
Attachments().
|
Attachments().
|
||||||
Get(ctx, options)
|
Get(ctx, options)
|
||||||
if err != nil {
|
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())
|
event.SetAttachments(attached.GetValue())
|
||||||
@ -144,12 +144,12 @@ func (c Events) EnumerateContainers(
|
|||||||
) error {
|
) error {
|
||||||
service, err := c.service()
|
service, err := c.service()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ofc, err := optionsForCalendars([]string{"name"})
|
ofc, err := optionsForCalendars([]string{"name"})
|
||||||
if err != nil {
|
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()
|
el := errs.Local()
|
||||||
@ -162,7 +162,7 @@ func (c Events) EnumerateContainers(
|
|||||||
|
|
||||||
resp, err := builder.Get(ctx, ofc)
|
resp, err := builder.Get(ctx, ofc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cal := range resp.GetValue() {
|
for _, cal := range resp.GetValue() {
|
||||||
@ -172,11 +172,7 @@ func (c Events) EnumerateContainers(
|
|||||||
|
|
||||||
cd := CalendarDisplayable{Calendarable: cal}
|
cd := CalendarDisplayable{Calendarable: cal}
|
||||||
if err := checkIDAndName(cd); err != nil {
|
if err := checkIDAndName(cd); err != nil {
|
||||||
el.AddRecoverable(clues.Stack(err).
|
errs.AddRecoverable(graph.Stack(ctx, err).Label(fault.LabelForceNoBackupCreation))
|
||||||
WithClues(ctx).
|
|
||||||
With(graph.ErrData(err)...).
|
|
||||||
Label(fault.LabelForceNoBackupCreation))
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,11 +186,7 @@ func (c Events) EnumerateContainers(
|
|||||||
path.Builder{}.Append(ptr.Val(cd.GetId())), // storage path
|
path.Builder{}.Append(ptr.Val(cd.GetId())), // storage path
|
||||||
path.Builder{}.Append(ptr.Val(cd.GetDisplayName()))) // display location
|
path.Builder{}.Append(ptr.Val(cd.GetDisplayName()))) // display location
|
||||||
if err := fn(temp); err != nil {
|
if err := fn(temp); err != nil {
|
||||||
el.AddRecoverable(clues.Stack(err).
|
errs.AddRecoverable(graph.Stack(fctx, err).Label(fault.LabelForceNoBackupCreation))
|
||||||
WithClues(fctx).
|
|
||||||
With(graph.ErrData(err)...).
|
|
||||||
Label(fault.LabelForceNoBackupCreation))
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,7 +221,7 @@ type eventPager struct {
|
|||||||
func (p *eventPager) getPage(ctx context.Context) (api.DeltaPageLinker, error) {
|
func (p *eventPager) getPage(ctx context.Context) (api.DeltaPageLinker, error) {
|
||||||
resp, err := p.builder.Get(ctx, p.options)
|
resp, err := p.builder.Get(ctx, p.options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -272,7 +264,7 @@ func (c Events) GetAddedAndRemovedItemIDs(
|
|||||||
// only return on error if it is NOT a delta issue.
|
// only return on error if it is NOT a delta issue.
|
||||||
// on bad deltas we retry the call with the regular builder
|
// on bad deltas we retry the call with the regular builder
|
||||||
if !graph.IsErrInvalidDelta(err) {
|
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
|
resetDelta = true
|
||||||
@ -335,12 +327,12 @@ func (c Events) Serialize(
|
|||||||
defer writer.Close()
|
defer writer.Close()
|
||||||
|
|
||||||
if err = writer.WriteObjectValue("", event); err != nil {
|
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()
|
bs, err := writer.GetSerializedContent()
|
||||||
if err != nil {
|
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
|
return bs, nil
|
||||||
|
|||||||
@ -50,7 +50,7 @@ func (c Mail) CreateMailFolder(
|
|||||||
|
|
||||||
mdl, err := c.stable.Client().UsersById(user).MailFolders().Post(ctx, requestBody, nil)
|
mdl, err := c.stable.Client().UsersById(user).MailFolders().Post(ctx, requestBody, nil)
|
||||||
if err != 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
|
return mdl, nil
|
||||||
@ -62,7 +62,7 @@ func (c Mail) CreateMailFolderWithParent(
|
|||||||
) (models.MailFolderable, error) {
|
) (models.MailFolderable, error) {
|
||||||
service, err := c.service()
|
service, err := c.service()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
isHidden := false
|
isHidden := false
|
||||||
@ -77,7 +77,7 @@ func (c Mail) CreateMailFolderWithParent(
|
|||||||
ChildFolders().
|
ChildFolders().
|
||||||
Post(ctx, requestBody, nil)
|
Post(ctx, requestBody, nil)
|
||||||
if err != 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
|
return mdl, nil
|
||||||
@ -91,7 +91,7 @@ func (c Mail) DeleteContainer(
|
|||||||
) error {
|
) error {
|
||||||
err := c.stable.Client().UsersById(user).MailFoldersById(folderID).Delete(ctx, nil)
|
err := c.stable.Client().UsersById(user).MailFoldersById(folderID).Delete(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -103,17 +103,17 @@ func (c Mail) GetContainerByID(
|
|||||||
) (graph.Container, error) {
|
) (graph.Container, error) {
|
||||||
service, err := c.service()
|
service, err := c.service()
|
||||||
if err != nil {
|
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"})
|
ofmf, err := optionsForMailFoldersItem([]string{"displayName", "parentFolderId"})
|
||||||
if err != nil {
|
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)
|
resp, err := service.Client().UsersById(userID).MailFoldersById(dirID).Get(ctx, ofmf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -128,7 +128,7 @@ func (c Mail) GetItem(
|
|||||||
) (serialization.Parsable, *details.ExchangeInfo, error) {
|
) (serialization.Parsable, *details.ExchangeInfo, error) {
|
||||||
mail, err := c.stable.Client().UsersById(user).MessagesById(itemID).Get(ctx, nil)
|
mail, err := c.stable.Client().UsersById(user).MessagesById(itemID).Get(ctx, nil)
|
||||||
if err != 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()) {
|
if *mail.GetHasAttachments() || HasAttachments(mail.GetBody()) {
|
||||||
@ -145,7 +145,7 @@ func (c Mail) GetItem(
|
|||||||
Attachments().
|
Attachments().
|
||||||
Get(ctx, options)
|
Get(ctx, options)
|
||||||
if err != nil {
|
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())
|
mail.SetAttachments(attached.GetValue())
|
||||||
@ -167,7 +167,7 @@ func (c Mail) EnumerateContainers(
|
|||||||
) error {
|
) error {
|
||||||
service, err := c.service()
|
service, err := c.service()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
el := errs.Local()
|
el := errs.Local()
|
||||||
@ -183,7 +183,7 @@ func (c Mail) EnumerateContainers(
|
|||||||
|
|
||||||
resp, err := builder.Get(ctx, nil)
|
resp, err := builder.Get(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range resp.GetValue() {
|
for _, v := range resp.GetValue() {
|
||||||
@ -198,11 +198,7 @@ func (c Mail) EnumerateContainers(
|
|||||||
|
|
||||||
temp := graph.NewCacheFolder(v, nil, nil)
|
temp := graph.NewCacheFolder(v, nil, nil)
|
||||||
if err := fn(temp); err != nil {
|
if err := fn(temp); err != nil {
|
||||||
el.AddRecoverable(clues.Stack(err).
|
errs.AddRecoverable(graph.Stack(fctx, err).Label(fault.LabelForceNoBackupCreation))
|
||||||
WithClues(fctx).
|
|
||||||
With(graph.ErrData(err)...).
|
|
||||||
Label(fault.LabelForceNoBackupCreation))
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -233,7 +229,7 @@ type mailPager struct {
|
|||||||
func (p *mailPager) getPage(ctx context.Context) (api.DeltaPageLinker, error) {
|
func (p *mailPager) getPage(ctx context.Context) (api.DeltaPageLinker, error) {
|
||||||
page, err := p.builder.Get(ctx, p.options)
|
page, err := p.builder.Get(ctx, p.options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return page, nil
|
return page, nil
|
||||||
@ -271,7 +267,7 @@ func (c Mail) GetAddedAndRemovedItemIDs(
|
|||||||
return nil,
|
return nil,
|
||||||
nil,
|
nil,
|
||||||
DeltaUpdate{},
|
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 {
|
if len(oldDelta) > 0 {
|
||||||
@ -341,12 +337,12 @@ func (c Mail) Serialize(
|
|||||||
defer writer.Close()
|
defer writer.Close()
|
||||||
|
|
||||||
if err = writer.WriteObjectValue("", msg); err != nil {
|
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()
|
bs, err := writer.GetSerializedContent()
|
||||||
if err != nil {
|
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
|
return bs, nil
|
||||||
|
|||||||
@ -74,14 +74,14 @@ func getItemsAddedAndRemovedFromContainer(
|
|||||||
// get the next page of data, check for standard errors
|
// get the next page of data, check for standard errors
|
||||||
resp, err := pager.getPage(ctx)
|
resp, err := pager.getPage(ctx)
|
||||||
if err != nil {
|
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
|
// each category type responds with a different interface, but all
|
||||||
// of them comply with GetValue, which is where we'll get our item data.
|
// of them comply with GetValue, which is where we'll get our item data.
|
||||||
items, err := pager.valuesIn(resp)
|
items, err := pager.valuesIn(resp)
|
||||||
if err != nil {
|
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)
|
itemCount += len(items)
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package exchange
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||||
msusers "github.com/microsoftgraph/msgraph-sdk-go/users"
|
msusers "github.com/microsoftgraph/msgraph-sdk-go/users"
|
||||||
|
|
||||||
@ -44,7 +43,7 @@ func (mau *mailAttachmentUploader) uploadSmallAttachment(ctx context.Context, at
|
|||||||
Attachments().
|
Attachments().
|
||||||
Post(ctx, attach, nil)
|
Post(ctx, attach, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -68,7 +67,7 @@ func (mau *mailAttachmentUploader) uploadSession(
|
|||||||
CreateUploadSession().
|
CreateUploadSession().
|
||||||
Post(ctx, session, nil)
|
Post(ctx, session, nil)
|
||||||
if err != 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
|
return r, nil
|
||||||
@ -94,7 +93,7 @@ func (eau *eventAttachmentUploader) uploadSmallAttachment(ctx context.Context, a
|
|||||||
Attachments().
|
Attachments().
|
||||||
Post(ctx, attach, nil)
|
Post(ctx, attach, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -116,7 +115,7 @@ func (eau *eventAttachmentUploader) uploadSession(
|
|||||||
CreateUploadSession().
|
CreateUploadSession().
|
||||||
Post(ctx, session, nil)
|
Post(ctx, session, nil)
|
||||||
if err != 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
|
return r, nil
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/alcionai/corso/src/internal/connector/exchange/api"
|
"github.com/alcionai/corso/src/internal/connector/exchange/api"
|
||||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
"github.com/alcionai/corso/src/internal/connector/graph"
|
||||||
"github.com/alcionai/corso/src/internal/connector/mockconnector"
|
"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/internal/tester"
|
||||||
"github.com/alcionai/corso/src/pkg/account"
|
"github.com/alcionai/corso/src/pkg/account"
|
||||||
"github.com/alcionai/corso/src/pkg/control"
|
"github.com/alcionai/corso/src/pkg/control"
|
||||||
@ -89,7 +88,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreContact() {
|
|||||||
control.Copy,
|
control.Copy,
|
||||||
folderID,
|
folderID,
|
||||||
userID)
|
userID)
|
||||||
assert.NoError(t, err, support.ConnectorStackErrorTrace(err))
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, info, "contact item info")
|
assert.NotNil(t, info, "contact item info")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +122,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreEvent() {
|
|||||||
calendarID,
|
calendarID,
|
||||||
userID,
|
userID,
|
||||||
fault.New(true))
|
fault.New(true))
|
||||||
assert.NoError(t, err, support.ConnectorStackErrorTrace(err))
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, info, "event item info")
|
assert.NotNil(t, info, "event item info")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +351,7 @@ func (suite *ExchangeRestoreSuite) TestRestoreExchangeObject() {
|
|||||||
destination,
|
destination,
|
||||||
userID,
|
userID,
|
||||||
fault.New(true))
|
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, info, "item info was not populated")
|
||||||
assert.NotNil(t, deleters)
|
assert.NotNil(t, deleters)
|
||||||
assert.NoError(t, deleters[test.category].DeleteContainer(ctx, userID, destination))
|
assert.NoError(t, deleters[test.category].DeleteContainer(ctx, userID, destination))
|
||||||
|
|||||||
@ -70,14 +70,14 @@ func RestoreExchangeContact(
|
|||||||
) (*details.ExchangeInfo, error) {
|
) (*details.ExchangeInfo, error) {
|
||||||
contact, err := support.CreateContactFromBytes(bits)
|
contact, err := support.CreateContactFromBytes(bits)
|
||||||
if err != nil {
|
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()))
|
ctx = clues.Add(ctx, "item_id", ptr.Val(contact.GetId()))
|
||||||
|
|
||||||
response, err := service.Client().UsersById(user).ContactFoldersById(destination).Contacts().Post(ctx, contact, nil)
|
response, err := service.Client().UsersById(user).ContactFoldersById(destination).Contacts().Post(ctx, contact, nil)
|
||||||
if err != 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 {
|
if response == nil {
|
||||||
@ -125,7 +125,7 @@ func RestoreExchangeEvent(
|
|||||||
|
|
||||||
response, err := service.Client().UsersById(user).CalendarsById(destination).Events().Post(ctx, transformedEvent, nil)
|
response, err := service.Client().UsersById(user).CalendarsById(destination).Events().Post(ctx, transformedEvent, nil)
|
||||||
if err != 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 {
|
if response == nil {
|
||||||
@ -249,7 +249,7 @@ func SendMailToBackStore(
|
|||||||
|
|
||||||
response, err := service.Client().UsersById(user).MailFoldersById(destination).Messages().Post(ctx, message, nil)
|
response, err := service.Client().UsersById(user).MailFoldersById(destination).Messages().Post(ctx, message, nil)
|
||||||
if err != 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 {
|
if response == nil {
|
||||||
@ -609,7 +609,7 @@ func establishMailRestoreLocation(
|
|||||||
temp, err := ac.Mail().CreateMailFolderWithParent(ctx, user, folder, folderID)
|
temp, err := ac.Mail().CreateMailFolderWithParent(ctx, user, folder, folderID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Should only error if cache malfunctions or incorrect parameters
|
// Should only error if cache malfunctions or incorrect parameters
|
||||||
return "", errors.Wrap(err, support.ConnectorStackErrorTrace(err))
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
folderID = *temp.GetId()
|
folderID = *temp.GetId()
|
||||||
@ -658,7 +658,7 @@ func establishContactsRestoreLocation(
|
|||||||
|
|
||||||
temp, err := ac.Contacts().CreateContactFolder(ctx, user, folders[0])
|
temp, err := ac.Contacts().CreateContactFolder(ctx, user, folders[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, support.ConnectorStackErrorTrace(err))
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
folderID := *temp.GetId()
|
folderID := *temp.GetId()
|
||||||
@ -695,7 +695,7 @@ func establishEventsRestoreLocation(
|
|||||||
|
|
||||||
temp, err := ac.Events().CreateCalendar(ctx, user, folders[0])
|
temp, err := ac.Events().CreateCalendar(ctx, user, folders[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrap(err, support.ConnectorStackErrorTrace(err))
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
folderID := *temp.GetId()
|
folderID := *temp.GetId()
|
||||||
|
|||||||
@ -56,18 +56,20 @@ func (suite *BetaClientSuite) TestCreateBetaClient() {
|
|||||||
func (suite *BetaClientSuite) TestBasicClientGetFunctionality() {
|
func (suite *BetaClientSuite) TestBasicClientGetFunctionality() {
|
||||||
ctx, flush := tester.NewContext()
|
ctx, flush := tester.NewContext()
|
||||||
defer flush()
|
defer flush()
|
||||||
|
|
||||||
t := suite.T()
|
t := suite.T()
|
||||||
|
|
||||||
adpt, err := graph.CreateAdapter(
|
adpt, err := graph.CreateAdapter(
|
||||||
suite.credentials.AzureTenantID,
|
suite.credentials.AzureTenantID,
|
||||||
suite.credentials.AzureClientID,
|
suite.credentials.AzureClientID,
|
||||||
suite.credentials.AzureClientSecret,
|
suite.credentials.AzureClientSecret)
|
||||||
)
|
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client := NewBetaClient(adpt)
|
client := NewBetaClient(adpt)
|
||||||
require.NotNil(t, client)
|
require.NotNil(t, client)
|
||||||
|
|
||||||
siteID := tester.M365SiteID(t)
|
siteID := tester.M365SiteID(t)
|
||||||
|
|
||||||
// TODO(dadams39) document allowable calls in main
|
// TODO(dadams39) document allowable calls in main
|
||||||
collection, err := client.SitesById(siteID).Pages().Get(ctx, nil)
|
collection, err := client.SitesById(siteID).Pages().Get(ctx, nil)
|
||||||
// Ensures that the client is able to receive data from beta
|
// Ensures that the client is able to receive data from beta
|
||||||
|
|||||||
@ -12,7 +12,9 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
|
||||||
|
"github.com/alcionai/clues"
|
||||||
"github.com/alcionai/corso/src/internal/common"
|
"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")
|
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
|
// The folder or item was deleted between the time we identified
|
||||||
// it and when we tried to fetch data for it.
|
// it and when we tried to fetch data for it.
|
||||||
type ErrDeletedInFlight struct {
|
type ErrDeletedInFlight struct {
|
||||||
@ -196,43 +209,74 @@ func hasErrorCode(err error, codes ...string) bool {
|
|||||||
return slices.Contains(lcodes, strings.ToLower(*oDataError.GetError().GetCode()))
|
return slices.Contains(lcodes, strings.ToLower(*oDataError.GetError().GetCode()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrData is a helper function that extracts ODataError metadata from
|
// Wrap is a helper function that extracts ODataError metadata from
|
||||||
// the error. If the error is not an ODataError type, returns an empty
|
// the error. If the error is not an ODataError type, returns the error.
|
||||||
// slice. The returned value is guaranteed to be an even-length pairing
|
func Wrap(ctx context.Context, e error, msg string) *clues.Err {
|
||||||
// of key, value tuples.
|
|
||||||
func ErrData(e error) []any {
|
|
||||||
result := make([]any, 0)
|
|
||||||
|
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return result
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
odErr, ok := e.(odataerrors.ODataErrorable)
|
odErr, ok := e.(odataerrors.ODataErrorable)
|
||||||
if !ok {
|
if !ok {
|
||||||
return result
|
return clues.Wrap(e, msg).WithClues(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get MainError
|
data, innerMsg := errData(odErr)
|
||||||
mainErr := odErr.GetError()
|
|
||||||
|
|
||||||
result = appendIf(result, "odataerror_code", mainErr.GetCode())
|
return setLabels(clues.Wrap(e, msg).WithClues(ctx).With(data...), innerMsg)
|
||||||
result = appendIf(result, "odataerror_message", mainErr.GetMessage())
|
}
|
||||||
result = appendIf(result, "odataerror_target", mainErr.GetTarget())
|
|
||||||
|
// 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() {
|
for i, d := range mainErr.GetDetails() {
|
||||||
pfx := fmt.Sprintf("odataerror_details_%d_", i)
|
pfx := fmt.Sprintf("odataerror_details_%d_", i)
|
||||||
result = appendIf(result, pfx+"code", d.GetCode())
|
data = appendIf(data, pfx+"code", d.GetCode())
|
||||||
result = appendIf(result, pfx+"message", d.GetMessage())
|
data = appendIf(data, pfx+"message", d.GetMessage())
|
||||||
result = appendIf(result, pfx+"target", d.GetTarget())
|
data = appendIf(data, pfx+"target", d.GetTarget())
|
||||||
|
msgConcat += ptr.Val(d.GetMessage())
|
||||||
}
|
}
|
||||||
|
|
||||||
inner := mainErr.GetInnererror()
|
inner := mainErr.GetInnererror()
|
||||||
if inner != nil {
|
if inner != nil {
|
||||||
result = appendIf(result, "odataerror_inner_cli_req_id", inner.GetClientRequestId())
|
data = appendIf(data, "odataerror_inner_cli_req_id", inner.GetClientRequestId())
|
||||||
result = appendIf(result, "odataerror_inner_req_id", inner.GetRequestId())
|
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 {
|
func appendIf(a []any, k string, v *string) []any {
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
|
||||||
backoff "github.com/cenkalti/backoff/v4"
|
backoff "github.com/cenkalti/backoff/v4"
|
||||||
khttp "github.com/microsoft/kiota-http-go"
|
khttp "github.com/microsoft/kiota-http-go"
|
||||||
)
|
)
|
||||||
@ -50,10 +49,7 @@ func (middleware RetryHandler) retryRequest(
|
|||||||
|
|
||||||
response, err := pipeline.Next(req, middlewareIndex)
|
response, err := pipeline.Next(req, middlewareIndex)
|
||||||
if err != nil && !IsErrTimeout(err) {
|
if err != nil && !IsErrTimeout(err) {
|
||||||
return response, clues.Stack(err).
|
return response, Stack(ctx, err).With("retry_count", executionCount)
|
||||||
WithClues(ctx).
|
|
||||||
With("retry_count", executionCount).
|
|
||||||
With(ErrData(err)...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return middleware.retryRequest(ctx,
|
return middleware.retryRequest(ctx,
|
||||||
@ -68,10 +64,7 @@ func (middleware RetryHandler) retryRequest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if respErr != nil {
|
if respErr != nil {
|
||||||
return nil, clues.Stack(respErr).
|
return nil, Stack(ctx, respErr).With("retry_count", executionCount)
|
||||||
WithClues(ctx).
|
|
||||||
With("retry_count", executionCount).
|
|
||||||
With(ErrData(respErr)...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||||
"github.com/alcionai/clues"
|
|
||||||
backoff "github.com/cenkalti/backoff/v4"
|
backoff "github.com/cenkalti/backoff/v4"
|
||||||
"github.com/microsoft/kiota-abstractions-go/serialization"
|
"github.com/microsoft/kiota-abstractions-go/serialization"
|
||||||
ka "github.com/microsoft/kiota-authentication-azure-go"
|
ka "github.com/microsoft/kiota-authentication-azure-go"
|
||||||
@ -343,7 +342,7 @@ func (middleware RetryHandler) Intercept(
|
|||||||
|
|
||||||
response, err := pipeline.Next(req, middlewareIndex)
|
response, err := pipeline.Next(req, middlewareIndex)
|
||||||
if err != nil && !IsErrTimeout(err) {
|
if err != nil && !IsErrTimeout(err) {
|
||||||
return response, clues.Stack(err).WithClues(ctx).With(ErrData(err)...)
|
return response, Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
exponentialBackOff := backoff.NewExponentialBackOff()
|
exponentialBackOff := backoff.NewExponentialBackOff()
|
||||||
@ -361,7 +360,7 @@ func (middleware RetryHandler) Intercept(
|
|||||||
exponentialBackOff,
|
exponentialBackOff,
|
||||||
err)
|
err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(ErrData(err)...)
|
return nil, Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
|
|||||||
@ -280,14 +280,12 @@ func getResources(
|
|||||||
|
|
||||||
response, err := query(ctx, gs)
|
response, err := query(ctx, gs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Wrap(err, "retrieving tenant's resources").
|
return nil, graph.Wrap(ctx, err, "retrieving tenant's resources")
|
||||||
WithClues(ctx).
|
|
||||||
With(graph.ErrData(err)...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iter, err := msgraphgocore.NewPageIterator(response, gs.Adapter(), parser)
|
iter, err := msgraphgocore.NewPageIterator(response, gs.Adapter(), parser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
el := errs.Local()
|
el := errs.Local()
|
||||||
@ -314,7 +312,7 @@ func getResources(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := iter.Iterate(ctx, callbackFunc); err != nil {
|
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()
|
return resources, el.Failure()
|
||||||
|
|||||||
@ -5,15 +5,14 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"golang.org/x/exp/maps"
|
"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/graph"
|
||||||
"github.com/alcionai/corso/src/internal/connector/mockconnector"
|
"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/data"
|
||||||
"github.com/alcionai/corso/src/internal/tester"
|
"github.com/alcionai/corso/src/internal/tester"
|
||||||
"github.com/alcionai/corso/src/internal/version"
|
"github.com/alcionai/corso/src/internal/version"
|
||||||
@ -325,19 +324,15 @@ func mustGetDefaultDriveID(
|
|||||||
//revive:enable:context-as-argument
|
//revive:enable:context-as-argument
|
||||||
d, err := service.Client().UsersById(userID).Drive().Get(ctx, nil)
|
d, err := service.Client().UsersById(userID).Drive().Get(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrapf(
|
err = graph.Wrap(ctx, err, "retrieving drive")
|
||||||
err,
|
|
||||||
"failed to retrieve default user drive. user: %s, details: %s",
|
|
||||||
userID,
|
|
||||||
support.ConnectorStackErrorTrace(err),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, err)
|
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(
|
func getCollectionsAndExpected(
|
||||||
|
|||||||
@ -69,7 +69,7 @@ func (p *driveItemPager) GetPage(ctx context.Context) (api.DeltaPageLinker, erro
|
|||||||
|
|
||||||
resp, err = p.builder.Get(ctx, p.options)
|
resp, err = p.builder.Get(ctx, p.options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
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)
|
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) {
|
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)
|
resp, err = p.builder.Get(ctx, p.options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
@ -194,7 +197,7 @@ func (p *siteDrivePager) GetDriveIDByName(ctx context.Context, driveName string)
|
|||||||
for {
|
for {
|
||||||
resp, err := p.builder.Get(ctx, p.options)
|
resp, err := p.builder.Get(ctx, p.options)
|
||||||
if err != nil {
|
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() {
|
for _, entry := range resp.GetValue() {
|
||||||
@ -230,7 +233,7 @@ func (p *siteDrivePager) GetFolderIDByName(ctx context.Context, driveID, folderN
|
|||||||
for {
|
for {
|
||||||
resp, err := builder.Get(ctx, option)
|
resp, err := builder.Get(ctx, option)
|
||||||
if err != nil {
|
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() {
|
for _, entry := range resp.GetValue() {
|
||||||
|
|||||||
@ -88,6 +88,7 @@ type Collection struct {
|
|||||||
|
|
||||||
// itemReadFunc returns a reader for the specified item
|
// itemReadFunc returns a reader for the specified item
|
||||||
type itemReaderFunc func(
|
type itemReaderFunc func(
|
||||||
|
ctx context.Context,
|
||||||
hc *http.Client,
|
hc *http.Client,
|
||||||
item models.DriveItemable,
|
item models.DriveItemable,
|
||||||
) (details.ItemInfo, io.ReadCloser, error)
|
) (details.ItemInfo, io.ReadCloser, error)
|
||||||
@ -395,7 +396,7 @@ func (oc *Collection) populateItems(ctx context.Context, errs *fault.Bus) {
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
_, itemData, err = oc.itemReader(oc.itemClient, item)
|
_, itemData, err = oc.itemReader(ctx, oc.itemClient, item)
|
||||||
|
|
||||||
if err != nil && graph.IsErrUnauthorized(err) {
|
if err != nil && graph.IsErrUnauthorized(err) {
|
||||||
// assume unauthorized requests are a sign of an expired
|
// assume unauthorized requests are a sign of an expired
|
||||||
|
|||||||
@ -94,7 +94,7 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
|
|||||||
numInstances: 1,
|
numInstances: 1,
|
||||||
source: OneDriveSource,
|
source: OneDriveSource,
|
||||||
itemDeets: nst{testItemName, 42, now},
|
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}},
|
return details.ItemInfo{OneDrive: &details.OneDriveInfo{ItemName: testItemName, Modified: now}},
|
||||||
io.NopCloser(bytes.NewReader(testItemData)),
|
io.NopCloser(bytes.NewReader(testItemData)),
|
||||||
nil
|
nil
|
||||||
@ -109,7 +109,7 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
|
|||||||
numInstances: 3,
|
numInstances: 3,
|
||||||
source: OneDriveSource,
|
source: OneDriveSource,
|
||||||
itemDeets: nst{testItemName, 42, now},
|
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}},
|
return details.ItemInfo{OneDrive: &details.OneDriveInfo{ItemName: testItemName, Modified: now}},
|
||||||
io.NopCloser(bytes.NewReader(testItemData)),
|
io.NopCloser(bytes.NewReader(testItemData)),
|
||||||
nil
|
nil
|
||||||
@ -124,7 +124,7 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
|
|||||||
numInstances: 1,
|
numInstances: 1,
|
||||||
source: SharePointSource,
|
source: SharePointSource,
|
||||||
itemDeets: nst{testItemName, 42, now},
|
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}},
|
return details.ItemInfo{SharePoint: &details.SharePointInfo{ItemName: testItemName, Modified: now}},
|
||||||
io.NopCloser(bytes.NewReader(testItemData)),
|
io.NopCloser(bytes.NewReader(testItemData)),
|
||||||
nil
|
nil
|
||||||
@ -139,7 +139,7 @@ func (suite *CollectionUnitTestSuite) TestCollection() {
|
|||||||
numInstances: 3,
|
numInstances: 3,
|
||||||
source: SharePointSource,
|
source: SharePointSource,
|
||||||
itemDeets: nst{testItemName, 42, now},
|
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}},
|
return details.ItemInfo{SharePoint: &details.SharePointInfo{ItemName: testItemName, Modified: now}},
|
||||||
io.NopCloser(bytes.NewReader(testItemData)),
|
io.NopCloser(bytes.NewReader(testItemData)),
|
||||||
nil
|
nil
|
||||||
@ -326,7 +326,11 @@ func (suite *CollectionUnitTestSuite) TestCollectionReadError() {
|
|||||||
mockItem.SetLastModifiedDateTime(&now)
|
mockItem.SetLastModifiedDateTime(&now)
|
||||||
coll.Add(mockItem)
|
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
|
return details.ItemInfo{}, nil, assert.AnError
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,6 +411,7 @@ func (suite *CollectionUnitTestSuite) TestCollectionPermissionBackupLatestModTim
|
|||||||
coll.Add(mockItem)
|
coll.Add(mockItem)
|
||||||
|
|
||||||
coll.itemReader = func(
|
coll.itemReader = func(
|
||||||
|
context.Context,
|
||||||
*http.Client,
|
*http.Client,
|
||||||
models.DriveItemable,
|
models.DriveItemable,
|
||||||
) (details.ItemInfo, io.ReadCloser, error) {
|
) (details.ItemInfo, io.ReadCloser, error) {
|
||||||
|
|||||||
@ -267,7 +267,7 @@ func (c *Collections) Get(
|
|||||||
// Enumerate drives for the specified resourceOwner
|
// Enumerate drives for the specified resourceOwner
|
||||||
pager, err := c.drivePagerFunc(c.source, c.service, c.resourceOwner, nil)
|
pager, err := c.drivePagerFunc(c.source, c.service, c.resourceOwner, nil)
|
||||||
if err != 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
|
retry := c.source == OneDriveSource
|
||||||
|
|||||||
@ -16,7 +16,6 @@ import (
|
|||||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
"github.com/alcionai/corso/src/internal/connector/graph"
|
||||||
gapi "github.com/alcionai/corso/src/internal/connector/graph/api"
|
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/onedrive/api"
|
||||||
"github.com/alcionai/corso/src/internal/connector/support"
|
|
||||||
"github.com/alcionai/corso/src/pkg/fault"
|
"github.com/alcionai/corso/src/pkg/fault"
|
||||||
"github.com/alcionai/corso/src/pkg/logger"
|
"github.com/alcionai/corso/src/pkg/logger"
|
||||||
)
|
)
|
||||||
@ -28,15 +27,10 @@ const (
|
|||||||
|
|
||||||
// nextLinkKey is used to find the next link in a paged
|
// nextLinkKey is used to find the next link in a paged
|
||||||
// graph response
|
// graph response
|
||||||
nextLinkKey = "@odata.nextLink"
|
nextLinkKey = "@odata.nextLink"
|
||||||
itemChildrenRawURLFmt = "https://graph.microsoft.com/v1.0/drives/%s/items/%s/children"
|
itemChildrenRawURLFmt = "https://graph.microsoft.com/v1.0/drives/%s/items/%s/children"
|
||||||
itemByPathRawURLFmt = "https://graph.microsoft.com/v1.0/drives/%s/items/%s:/%s"
|
itemByPathRawURLFmt = "https://graph.microsoft.com/v1.0/drives/%s/items/%s:/%s"
|
||||||
itemNotFoundErrorCode = "itemNotFound"
|
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"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeltaUpdate holds the results of a current delta token. It normally
|
// DeltaUpdate holds the results of a current delta token. It normally
|
||||||
@ -97,22 +91,17 @@ func drives(
|
|||||||
for i := 0; i <= numberOfRetries; i++ {
|
for i := 0; i <= numberOfRetries; i++ {
|
||||||
page, err = pager.GetPage(ctx)
|
page, err = pager.GetPage(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Various error handling. May return an error or perform a retry.
|
if clues.HasLabel(err, graph.Labels.MysiteNotFound) {
|
||||||
errMsg := support.ConnectorStackErrorTraceWrap(err, "").Error()
|
|
||||||
if strings.Contains(errMsg, userMysiteURLNotFound) ||
|
|
||||||
strings.Contains(errMsg, userMysiteURLNotFoundMsg) ||
|
|
||||||
strings.Contains(errMsg, userMysiteNotFound) ||
|
|
||||||
strings.Contains(errMsg, userMysiteNotFoundMsg) {
|
|
||||||
logger.Ctx(ctx).Infof("resource owner does not have a drive")
|
logger.Ctx(ctx).Infof("resource owner does not have a drive")
|
||||||
return make([]models.Driveable, 0), nil // no license or drives.
|
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)
|
time.Sleep(time.Duration(3*(i+1)) * time.Second)
|
||||||
continue
|
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
|
// No error encountered, break the retry loop so we can extract results
|
||||||
@ -122,7 +111,7 @@ func drives(
|
|||||||
|
|
||||||
tmp, err := pager.ValuesIn(page)
|
tmp, err := pager.ValuesIn(page)
|
||||||
if err != nil {
|
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...)
|
drives = append(drives, tmp...)
|
||||||
@ -232,14 +221,12 @@ func collectItems(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
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)
|
vals, err := pager.ValuesIn(page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return DeltaUpdate{}, nil, nil, clues.Wrap(err, "extracting items from response").
|
return DeltaUpdate{}, nil, nil, graph.Wrap(ctx, err, "extracting items from response")
|
||||||
WithClues(ctx).
|
|
||||||
With(graph.ErrData(err)...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = collector(
|
err = collector(
|
||||||
@ -297,15 +284,15 @@ func getFolder(
|
|||||||
foundItem, err = builder.Get(ctx, nil)
|
foundItem, err = builder.Get(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if graph.IsErrDeletedInFlight(err) {
|
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
|
// Check if the item found is a folder, fail the call if not
|
||||||
if foundItem.GetFolder() == nil {
|
if foundItem.GetFolder() == nil {
|
||||||
return nil, clues.Stack(errFolderNotFound).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, errFolderNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
return foundItem, nil
|
return foundItem, nil
|
||||||
@ -325,7 +312,7 @@ func createItem(
|
|||||||
|
|
||||||
newItem, err := builder.Post(ctx, newItem, nil)
|
newItem, err := builder.Post(ctx, newItem, nil)
|
||||||
if err != 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
|
return newItem, nil
|
||||||
@ -447,10 +434,7 @@ func DeleteItem(
|
|||||||
) error {
|
) error {
|
||||||
err := gs.Client().DrivesById(driveID).ItemsById(itemID).Delete(ctx, nil)
|
err := gs.Client().DrivesById(driveID).ItemsById(itemID).Delete(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return clues.Wrap(err, "deleting item").
|
return graph.Wrap(ctx, err, "deleting item").With("item_id", itemID)
|
||||||
WithClues(ctx).
|
|
||||||
With("item_id", itemID).
|
|
||||||
With(graph.ErrData(err)...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -12,10 +12,10 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/alcionai/clues"
|
||||||
"github.com/alcionai/corso/src/internal/common"
|
"github.com/alcionai/corso/src/internal/common"
|
||||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
"github.com/alcionai/corso/src/internal/connector/graph"
|
||||||
"github.com/alcionai/corso/src/internal/connector/graph/api"
|
"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/internal/tester"
|
||||||
"github.com/alcionai/corso/src/pkg/control"
|
"github.com/alcionai/corso/src/pkg/control"
|
||||||
"github.com/alcionai/corso/src/pkg/fault"
|
"github.com/alcionai/corso/src/pkg/fault"
|
||||||
@ -78,6 +78,11 @@ func TestOneDriveUnitSuite(t *testing.T) {
|
|||||||
suite.Run(t, &OneDriveUnitSuite{Suite: tester.NewUnitSuite(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 {
|
func odErr(code string) *odataerrors.ODataError {
|
||||||
odErr := &odataerrors.ODataError{}
|
odErr := &odataerrors.ODataError{}
|
||||||
merr := odataerrors.MainError{}
|
merr := odataerrors.MainError{}
|
||||||
@ -88,6 +93,9 @@ func odErr(code string) *odataerrors.ODataError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *OneDriveUnitSuite) TestDrives() {
|
func (suite *OneDriveUnitSuite) TestDrives() {
|
||||||
|
ctx, flush := tester.NewContext()
|
||||||
|
defer flush()
|
||||||
|
|
||||||
numDriveResults := 4
|
numDriveResults := 4
|
||||||
emptyLink := ""
|
emptyLink := ""
|
||||||
link := "foo"
|
link := "foo"
|
||||||
@ -95,18 +103,8 @@ func (suite *OneDriveUnitSuite) TestDrives() {
|
|||||||
// These errors won't be the "correct" format when compared to what graph
|
// 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
|
// returns, but they're close enough to have the same info when the inner
|
||||||
// details are extracted via support package.
|
// details are extracted via support package.
|
||||||
mySiteURLNotFound := support.ConnectorStackErrorTraceWrap(
|
mySiteURLNotFound := odErr(userMysiteURLNotFound)
|
||||||
odErr(userMysiteURLNotFound),
|
mySiteNotFound := odErr(userMysiteNotFound)
|
||||||
"maximum retries or unretryable",
|
|
||||||
)
|
|
||||||
mySiteNotFound := support.ConnectorStackErrorTraceWrap(
|
|
||||||
odErr(userMysiteNotFound),
|
|
||||||
"maximum retries or unretryable",
|
|
||||||
)
|
|
||||||
deadlineExceeded := support.ConnectorStackErrorTraceWrap(
|
|
||||||
odErr(contextDeadlineExceeded),
|
|
||||||
"maximum retries or unretryable",
|
|
||||||
)
|
|
||||||
|
|
||||||
resultDrives := make([]models.Driveable, 0, numDriveResults)
|
resultDrives := make([]models.Driveable, 0, numDriveResults)
|
||||||
|
|
||||||
@ -122,7 +120,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
|
|||||||
|
|
||||||
for i := 0; i < getDrivesRetries+1; i++ {
|
for i := 0; i < getDrivesRetries+1; i++ {
|
||||||
tooManyRetries = append(tooManyRetries, pagerResult{
|
tooManyRetries = append(tooManyRetries, pagerResult{
|
||||||
err: deadlineExceeded,
|
err: context.DeadlineExceeded,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +217,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
|
|||||||
{
|
{
|
||||||
drives: nil,
|
drives: nil,
|
||||||
nextLink: nil,
|
nextLink: nil,
|
||||||
err: mySiteURLNotFound,
|
err: graph.Stack(ctx, mySiteURLNotFound),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
retry: true,
|
retry: true,
|
||||||
@ -232,7 +230,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
|
|||||||
{
|
{
|
||||||
drives: nil,
|
drives: nil,
|
||||||
nextLink: nil,
|
nextLink: nil,
|
||||||
err: mySiteNotFound,
|
err: graph.Stack(ctx, mySiteNotFound),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
retry: true,
|
retry: true,
|
||||||
@ -250,7 +248,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
|
|||||||
{
|
{
|
||||||
drives: nil,
|
drives: nil,
|
||||||
nextLink: nil,
|
nextLink: nil,
|
||||||
err: deadlineExceeded,
|
err: context.DeadlineExceeded,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
drives: resultDrives[numDriveResults/2:],
|
drives: resultDrives[numDriveResults/2:],
|
||||||
@ -273,7 +271,7 @@ func (suite *OneDriveUnitSuite) TestDrives() {
|
|||||||
{
|
{
|
||||||
drives: nil,
|
drives: nil,
|
||||||
nextLink: nil,
|
nextLink: nil,
|
||||||
err: deadlineExceeded,
|
err: context.DeadlineExceeded,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
drives: resultDrives[numDriveResults/2:],
|
drives: resultDrives[numDriveResults/2:],
|
||||||
@ -437,9 +435,6 @@ func (fm testFolderMatcher) Matches(path string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *OneDriveSuite) TestOneDriveNewCollections() {
|
func (suite *OneDriveSuite) TestOneDriveNewCollections() {
|
||||||
ctx, flush := tester.NewContext()
|
|
||||||
defer flush()
|
|
||||||
|
|
||||||
creds, err := tester.NewM365Account(suite.T()).M365Config()
|
creds, err := tester.NewM365Account(suite.T()).M365Config()
|
||||||
require.NoError(suite.T(), err)
|
require.NoError(suite.T(), err)
|
||||||
|
|
||||||
@ -458,13 +453,18 @@ func (suite *OneDriveSuite) TestOneDriveNewCollections() {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
suite.Run(test.name, func() {
|
suite.Run(test.name, func() {
|
||||||
t := suite.T()
|
ctx, flush := tester.NewContext()
|
||||||
|
defer flush()
|
||||||
|
|
||||||
service := loadTestService(t)
|
var (
|
||||||
scope := selectors.
|
t = suite.T()
|
||||||
NewOneDriveBackup([]string{test.user}).
|
service = loadTestService(t)
|
||||||
AllData()[0]
|
scope = selectors.
|
||||||
odcs, excludes, err := NewCollections(
|
NewOneDriveBackup([]string{test.user}).
|
||||||
|
AllData()[0]
|
||||||
|
)
|
||||||
|
|
||||||
|
colls := NewCollections(
|
||||||
graph.HTTPClient(graph.NoTimeout()),
|
graph.HTTPClient(graph.NoTimeout()),
|
||||||
creds.AzureTenantID,
|
creds.AzureTenantID,
|
||||||
test.user,
|
test.user,
|
||||||
@ -472,9 +472,12 @@ func (suite *OneDriveSuite) TestOneDriveNewCollections() {
|
|||||||
testFolderMatcher{scope},
|
testFolderMatcher{scope},
|
||||||
service,
|
service,
|
||||||
service.updateStatus,
|
service.updateStatus,
|
||||||
control.Options{ToggleFeatures: control.Toggles{EnablePermissionsBackup: true}},
|
control.Options{
|
||||||
).Get(ctx, nil, fault.New(true))
|
ToggleFeatures: control.Toggles{EnablePermissionsBackup: true},
|
||||||
assert.NoError(t, err)
|
})
|
||||||
|
|
||||||
|
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.
|
// Don't expect excludes as this isn't an incremental backup.
|
||||||
assert.Empty(t, excludes)
|
assert.Empty(t, excludes)
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@ func getDriveItem(
|
|||||||
) (models.DriveItemable, error) {
|
) (models.DriveItemable, error) {
|
||||||
di, err := srv.Client().DrivesById(driveID).ItemsById(itemID).Get(ctx, nil)
|
di, err := srv.Client().DrivesById(driveID).ItemsById(itemID).Get(ctx, nil)
|
||||||
if err != 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
|
return di, nil
|
||||||
@ -46,10 +46,11 @@ func getDriveItem(
|
|||||||
// and using a http client to initialize a reader
|
// and using a http client to initialize a reader
|
||||||
// TODO: Add metadata fetching to SharePoint
|
// TODO: Add metadata fetching to SharePoint
|
||||||
func sharePointItemReader(
|
func sharePointItemReader(
|
||||||
|
ctx context.Context,
|
||||||
hc *http.Client,
|
hc *http.Client,
|
||||||
item models.DriveItemable,
|
item models.DriveItemable,
|
||||||
) (details.ItemInfo, io.ReadCloser, error) {
|
) (details.ItemInfo, io.ReadCloser, error) {
|
||||||
resp, err := downloadItem(hc, item)
|
resp, err := downloadItem(ctx, hc, item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return details.ItemInfo{}, nil, errors.Wrap(err, "downloading item")
|
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
|
// It crafts this by querying M365 for a download URL for the item
|
||||||
// and using a http client to initialize a reader
|
// and using a http client to initialize a reader
|
||||||
func oneDriveItemReader(
|
func oneDriveItemReader(
|
||||||
|
ctx context.Context,
|
||||||
hc *http.Client,
|
hc *http.Client,
|
||||||
item models.DriveItemable,
|
item models.DriveItemable,
|
||||||
) (details.ItemInfo, io.ReadCloser, error) {
|
) (details.ItemInfo, io.ReadCloser, error) {
|
||||||
@ -115,7 +117,7 @@ func oneDriveItemReader(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if isFile {
|
if isFile {
|
||||||
resp, err := downloadItem(hc, item)
|
resp, err := downloadItem(ctx, hc, item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return details.ItemInfo{}, nil, errors.Wrap(err, "downloading item")
|
return details.ItemInfo{}, nil, errors.Wrap(err, "downloading item")
|
||||||
}
|
}
|
||||||
@ -130,7 +132,7 @@ func oneDriveItemReader(
|
|||||||
return dii, rc, nil
|
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)
|
url, ok := item.GetAdditionalData()[downloadURLKey].(*string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, clues.New("extracting file url").With("item_id", ptr.Val(item.GetId()))
|
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)
|
req, err := http.NewRequest(http.MethodGet, *url, nil)
|
||||||
if err != 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
|
//nolint:lll
|
||||||
@ -229,12 +231,7 @@ func oneDriveItemPermissionInfo(
|
|||||||
Permissions().
|
Permissions().
|
||||||
Get(ctx, nil)
|
Get(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = clues.Wrap(err, "fetching item permissions").
|
return nil, graph.Wrap(ctx, err, "getting item metadata").With("item_id", id)
|
||||||
WithClues(ctx).
|
|
||||||
With("item_id", id).
|
|
||||||
With(graph.ErrData(err)...)
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uperms := filterUserPermissions(ctx, perm.GetValue())
|
uperms := filterUserPermissions(ctx, perm.GetValue())
|
||||||
@ -360,9 +357,7 @@ func driveItemWriter(
|
|||||||
|
|
||||||
r, err := service.Client().DrivesById(driveID).ItemsById(itemID).CreateUploadSession().Post(ctx, session, nil)
|
r, err := service.Client().DrivesById(driveID).ItemsById(itemID).CreateUploadSession().Post(ctx, session, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Wrap(err, "creating item upload session").
|
return nil, graph.Wrap(ctx, err, "creating item upload session")
|
||||||
WithClues(ctx).
|
|
||||||
With(graph.ErrData(err)...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Ctx(ctx).Debug("created an 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)
|
drive, err := service.Client().DrivesById(driveID).Get(ctx, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, clues.Stack(err).WithClues(ctx).With(graph.ErrData(err)...)
|
return nil, graph.Stack(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
orig.SetName(drive.GetName())
|
orig.SetName(drive.GetName())
|
||||||
|
|||||||
@ -111,7 +111,7 @@ func (suite *ItemIntegrationSuite) TestItemReader_oneDrive() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Read data for the file
|
// 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.NoError(suite.T(), err)
|
||||||
require.NotNil(suite.T(), itemInfo.OneDrive)
|
require.NotNil(suite.T(), itemInfo.OneDrive)
|
||||||
|
|||||||
@ -190,7 +190,7 @@ func restorePermissions(
|
|||||||
PermissionsById(permissionIDMappings[p.ID]).
|
PermissionsById(permissionIDMappings[p.ID]).
|
||||||
Delete(ctx, nil)
|
Delete(ctx, nil)
|
||||||
if err != 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)
|
np, err := service.Client().DrivesById(driveID).ItemsById(itemID).Invite().Post(ctx, pbody, nil)
|
||||||
if err != 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()
|
permissionIDMappings[p.ID] = *np.GetValue()[0].GetId()
|
||||||
|
|||||||
@ -474,7 +474,7 @@ func CreateRestoreFolders(
|
|||||||
) (string, error) {
|
) (string, error) {
|
||||||
driveRoot, err := service.Client().DrivesById(driveID).Root().Get(ctx, nil)
|
driveRoot, err := service.Client().DrivesById(driveID).Root().Get(ctx, nil)
|
||||||
if err != 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())
|
parentFolderID := ptr.Val(driveRoot.GetId())
|
||||||
@ -550,7 +550,7 @@ func restoreData(
|
|||||||
// Upload the stream data
|
// Upload the stream data
|
||||||
written, err := io.CopyBuffer(w, progReader, copyBuffer)
|
written, err := io.CopyBuffer(w, progReader, copyBuffer)
|
||||||
if err != nil {
|
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{}
|
dii := details.ItemInfo{}
|
||||||
|
|||||||
@ -70,7 +70,7 @@ func GetSitePages(
|
|||||||
|
|
||||||
page, err = serv.Client().SitesById(siteID).PagesById(pageID).Get(ctx, opts)
|
page, err = serv.Client().SitesById(siteID).PagesById(pageID).Get(ctx, opts)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ func FetchPages(ctx context.Context, bs *discover.BetaService, siteID string) ([
|
|||||||
for {
|
for {
|
||||||
resp, err = builder.Get(ctx, opts)
|
resp, err = builder.Get(ctx, opts)
|
||||||
if err != nil {
|
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() {
|
for _, entry := range resp.GetValue() {
|
||||||
@ -162,7 +162,7 @@ func DeleteSitePage(
|
|||||||
) error {
|
) error {
|
||||||
err := serv.Client().SitesById(siteID).PagesById(pageID).Delete(ctx, nil)
|
err := serv.Client().SitesById(siteID).PagesById(pageID).Delete(ctx, nil)
|
||||||
if err != 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
|
return nil
|
||||||
@ -222,7 +222,7 @@ func RestoreSitePage(
|
|||||||
// See: https://learn.microsoft.com/en-us/graph/api/sitepage-create?view=graph-rest-beta
|
// 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)
|
restoredPage, err := service.Client().SitesById(siteID).Pages().Post(ctx, page, nil)
|
||||||
if err != 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())
|
pageID = ptr.Val(restoredPage.GetId())
|
||||||
@ -240,7 +240,7 @@ func RestoreSitePage(
|
|||||||
Publish().
|
Publish().
|
||||||
Post(ctx, nil)
|
Post(ctx, nil)
|
||||||
if err != 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)))
|
dii.SharePoint = PageInfo(restoredPage, int64(len(byteArray)))
|
||||||
|
|||||||
@ -231,7 +231,7 @@ func (sc *Collection) retrieveLists(
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
byteArray, err := serializeContent(wtr, lst)
|
byteArray, err := serializeContent(ctx, wtr, lst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
el.AddRecoverable(clues.Wrap(err, "serializing list").WithClues(ctx).Label(fault.LabelForceNoBackupCreation))
|
el.AddRecoverable(clues.Wrap(err, "serializing list").WithClues(ctx).Label(fault.LabelForceNoBackupCreation))
|
||||||
continue
|
continue
|
||||||
@ -299,7 +299,7 @@ func (sc *Collection) retrievePages(
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
byteArray, err := serializeContent(wtr, pg)
|
byteArray, err := serializeContent(ctx, wtr, pg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
el.AddRecoverable(clues.Wrap(err, "serializing page").WithClues(ctx).Label(fault.LabelForceNoBackupCreation))
|
el.AddRecoverable(clues.Wrap(err, "serializing page").WithClues(ctx).Label(fault.LabelForceNoBackupCreation))
|
||||||
continue
|
continue
|
||||||
@ -324,17 +324,21 @@ func (sc *Collection) retrievePages(
|
|||||||
return metrics, el.Failure()
|
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()
|
defer writer.Close()
|
||||||
|
|
||||||
err := writer.WriteObjectValue("", obj)
|
err := writer.WriteObjectValue("", obj)
|
||||||
if err != nil {
|
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()
|
byteArray, err := writer.GetSerializedContent()
|
||||||
if err != nil {
|
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
|
return byteArray, nil
|
||||||
|
|||||||
@ -206,7 +206,7 @@ func (suite *SharePointCollectionSuite) TestListCollection_Restore() {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
resp, err := builder.Get(ctx, nil)
|
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() {
|
for _, temp := range resp.GetValue() {
|
||||||
if *temp.GetDisplayName() == deets.SharePoint.ItemName {
|
if *temp.GetDisplayName() == deets.SharePoint.ItemName {
|
||||||
|
|||||||
@ -191,7 +191,7 @@ func collectLibraries(
|
|||||||
// token-based incrementals.
|
// token-based incrementals.
|
||||||
odcs, excludes, err := colls.Get(ctx, nil, errs)
|
odcs, excludes, err := colls.Get(ctx, nil, errs)
|
||||||
if err != nil {
|
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
|
return append(collections, odcs...), excludes, nil
|
||||||
|
|||||||
@ -7,11 +7,9 @@ import (
|
|||||||
"github.com/alcionai/clues"
|
"github.com/alcionai/clues"
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||||
mssite "github.com/microsoftgraph/msgraph-sdk-go/sites"
|
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/common/ptr"
|
||||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
"github.com/alcionai/corso/src/internal/connector/graph"
|
||||||
"github.com/alcionai/corso/src/internal/connector/support"
|
|
||||||
"github.com/alcionai/corso/src/pkg/fault"
|
"github.com/alcionai/corso/src/pkg/fault"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,7 +44,7 @@ func preFetchLists(
|
|||||||
for {
|
for {
|
||||||
resp, err := builder.Get(ctx, options)
|
resp, err := builder.Get(ctx, options)
|
||||||
if err != nil {
|
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() {
|
for _, entry := range resp.GetValue() {
|
||||||
@ -131,7 +129,7 @@ func loadSiteLists(
|
|||||||
|
|
||||||
entry, err = gs.Client().SitesById(siteID).ListsById(id).Get(ctx, nil)
|
entry, err = gs.Client().SitesById(siteID).ListsById(id).Get(ctx, nil)
|
||||||
if err != 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +207,7 @@ func fetchListItems(
|
|||||||
|
|
||||||
resp, err := builder.Get(ctx, nil)
|
resp, err := builder.Get(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, support.ConnectorStackErrorTrace(err))
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, itm := range resp.GetValue() {
|
for _, itm := range resp.GetValue() {
|
||||||
@ -221,7 +219,7 @@ func fetchListItems(
|
|||||||
|
|
||||||
fields, err := newPrefix.Fields().Get(ctx, nil)
|
fields, err := newPrefix.Fields().Get(ctx, nil)
|
||||||
if err != 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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +255,7 @@ func fetchColumns(
|
|||||||
for {
|
for {
|
||||||
resp, err := builder.Get(ctx, nil)
|
resp, err := builder.Get(ctx, nil)
|
||||||
if err != 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()...)
|
cs = append(cs, resp.GetValue()...)
|
||||||
@ -274,7 +272,7 @@ func fetchColumns(
|
|||||||
for {
|
for {
|
||||||
resp, err := builder.Get(ctx, nil)
|
resp, err := builder.Get(ctx, nil)
|
||||||
if err != 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()...)
|
cs = append(cs, resp.GetValue()...)
|
||||||
@ -315,7 +313,7 @@ func fetchContentTypes(
|
|||||||
|
|
||||||
resp, err := builder.Get(ctx, nil)
|
resp, err := builder.Get(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, support.ConnectorStackErrorTrace(err))
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cont := range resp.GetValue() {
|
for _, cont := range resp.GetValue() {
|
||||||
@ -367,7 +365,7 @@ func fetchColumnLinks(
|
|||||||
for {
|
for {
|
||||||
resp, err := builder.Get(ctx, nil)
|
resp, err := builder.Get(ctx, nil)
|
||||||
if err != 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()...)
|
links = append(links, resp.GetValue()...)
|
||||||
@ -394,7 +392,7 @@ func DeleteList(
|
|||||||
) error {
|
) error {
|
||||||
err := gs.Client().SitesById(siteID).ListsById(listID).Delete(ctx, nil)
|
err := gs.Client().SitesById(siteID).ListsById(listID).Delete(ctx, nil)
|
||||||
if err != 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
|
return nil
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import (
|
|||||||
absser "github.com/microsoft/kiota-abstractions-go/serialization"
|
absser "github.com/microsoft/kiota-abstractions-go/serialization"
|
||||||
mssite "github.com/microsoftgraph/msgraph-sdk-go/sites"
|
mssite "github.com/microsoftgraph/msgraph-sdk-go/sites"
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
|
||||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
"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)
|
sites, err := gs.Client().Sites().Get(ctx, options)
|
||||||
if err != nil {
|
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
|
return sites, nil
|
||||||
|
|||||||
@ -126,7 +126,7 @@ func createRestoreFolders(
|
|||||||
// Get Main Drive for Site, Documents
|
// Get Main Drive for Site, Documents
|
||||||
mainDrive, err := service.Client().SitesById(siteID).Drive().Get(ctx, nil)
|
mainDrive, err := service.Client().SitesById(siteID).Drive().Get(ctx, nil)
|
||||||
if err != 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)
|
return onedrive.CreateRestoreFolders(ctx, service, *mainDrive.GetId(), restoreFolders)
|
||||||
@ -182,7 +182,7 @@ func restoreListItem(
|
|||||||
// Restore to List base to M365 back store
|
// Restore to List base to M365 back store
|
||||||
restoredList, err := service.Client().SitesById(siteID).Lists().Post(ctx, newList, nil)
|
restoredList, err := service.Client().SitesById(siteID).Lists().Post(ctx, newList, nil)
|
||||||
if err != 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
|
// Uploading of ListItems is conducted after the List is restored
|
||||||
@ -195,10 +195,8 @@ func restoreListItem(
|
|||||||
Items().
|
Items().
|
||||||
Post(ctx, lItem, nil)
|
Post(ctx, lItem, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return dii, clues.Wrap(err, "restoring list items").
|
return dii, graph.Wrap(ctx, err, "restoring list items").
|
||||||
With("restored_list_id", ptr.Val(restoredList.GetId())).
|
With("restored_list_id", ptr.Val(restoredList.GetId()))
|
||||||
WithClues(ctx).
|
|
||||||
With(graph.ErrData(err)...)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
|
||||||
}
|
|
||||||
@ -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)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1006,7 +1006,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchangeIncrementals() {
|
|||||||
require.NotEmpty(t, ids, "message ids in folder")
|
require.NotEmpty(t, ids, "message ids in folder")
|
||||||
|
|
||||||
err = cli.MessagesById(ids[0]).Delete(ctx, nil)
|
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:
|
case path.ContactsCategory:
|
||||||
ids, _, _, err := ac.Contacts().GetAddedAndRemovedItemIDs(ctx, suite.user, containerID, "")
|
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")
|
require.NotEmpty(t, ids, "contact ids in folder")
|
||||||
|
|
||||||
err = cli.ContactsById(ids[0]).Delete(ctx, nil)
|
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:
|
case path.EventsCategory:
|
||||||
ids, _, _, err := ac.Events().GetAddedAndRemovedItemIDs(ctx, suite.user, containerID, "")
|
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")
|
require.NotEmpty(t, ids, "event ids in folder")
|
||||||
|
|
||||||
err = cli.CalendarsById(ids[0]).Delete(ctx, nil)
|
err = cli.CalendarsById(ids[0]).Delete(ctx, nil)
|
||||||
require.NoError(t, err, "deleting calendar: %s", support.ConnectorStackErrorTrace(err))
|
require.NoError(t, err, "deleting calendar")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/alcionai/corso/src/cli/print"
|
"github.com/alcionai/corso/src/cli/print"
|
||||||
"github.com/alcionai/corso/src/internal/common"
|
"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/model"
|
||||||
"github.com/alcionai/corso/src/internal/stats"
|
"github.com/alcionai/corso/src/internal/stats"
|
||||||
"github.com/alcionai/corso/src/internal/version"
|
"github.com/alcionai/corso/src/internal/version"
|
||||||
@ -158,23 +157,13 @@ func (b Backup) Values() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b Backup) countErrors() int {
|
func (b Backup) countErrors() int {
|
||||||
errCount := b.ErrorCount
|
if b.ErrorCount > 0 {
|
||||||
if errCount > 0 {
|
return b.ErrorCount
|
||||||
return errCount
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// current tracking
|
errCount := len(b.Errors.Recovered)
|
||||||
if b.ReadErrors != nil || b.WriteErrors != nil {
|
if b.Errors.Failure != nil {
|
||||||
return support.GetNumberOfErrors(b.ReadErrors) + support.GetNumberOfErrors(b.WriteErrors)
|
errCount++
|
||||||
}
|
|
||||||
|
|
||||||
// future tracking
|
|
||||||
if b.Errors.Failure != nil || len(b.Errors.Recovered) > 0 {
|
|
||||||
if b.Errors.Failure != nil {
|
|
||||||
errCount++
|
|
||||||
}
|
|
||||||
|
|
||||||
errCount += len(b.Errors.Recovered)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return errCount
|
return errCount
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user