Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better way to match BatchResult with request #1374

Closed
1 task done
wizofaus opened this issue Feb 2, 2024 · 5 comments
Closed
1 task done

Better way to match BatchResult with request #1374

wizofaus opened this issue Feb 2, 2024 · 5 comments
Assignees
Labels
area: framework ⚙ Changes in the SDK core framework code question Further information is requested

Comments

@wizofaus
Copy link

wizofaus commented Feb 2, 2024

Category

  • Feature request

Describe the feature

Would like the ability to reliably/safely determine which BatchResult (as returned by IPnPContext.ExecuteQuery) matches with the corresponding BatchRequest.

Describe the solution you'd like

Something like

foreach (var id in idsToRecycle)
    idMap[id] = (await list.Items.RecycleByIdBatchAsync(id)).RequestId;

var batchResults = await pnpContext.ExecuteAsync(false);
foreach (var id in idsToRecycle)
    if (pnpContext.FindByRequestId(idMap[id]) is BatchResult result)
       ;// handle appropriately according to id 

Alternatively I'd be quite happy if RecycleByIdBatchAsync (and similar functions) returned back a BatchRequest object from which the BatchResult info was available explicitly after calling ExecuteAsync( ):

foreach (var id in idsToRecycle)
    idMap[id] = await list.Items.RecycleByIdBatchAsync(id);

var batchResults = await pnpContext.ExecuteAsync(false);
foreach (var id in idsToRecycle)
    if (idMap[id].Result is BatchResult result)
       ;// handle appropriately according to id 

Additional context

Currently have to do it by assuming that the BatchResult.ApiRequest string happens to match a particular pattern (e.g. /items(<id>)/recycle in this case).

@jansenbe
Copy link
Contributor

@wizofaus : BatchRequest is for the most part an internal class, only few properties are exposed to enable custom API calling to use batching. The BatchResult class returns all the information needed to understand the failed request and that information is copied from the starting BatchRequest.

As the various 'batch' methods return different types (adding a list item returns an IListItem, deleting an item returns nothing) there's no way for you capture the id of the created internal BatchRequest, therefore making it hard to later on link back to the BatchRequest.

What information in BatchRequest do you feel is missing for being able to realize your scenario?

@jansenbe jansenbe self-assigned this Feb 13, 2024
@jansenbe jansenbe added question Further information is requested area: framework ⚙ Changes in the SDK core framework code labels Feb 13, 2024
@wizofaus
Copy link
Author

wizofaus commented Feb 13, 2024 via email

@jansenbe
Copy link
Contributor

@wizofaus : What I can do is make the Id of the BatchRequest public and make that Id also appear in the BatchResult. This then allows you to track whatever you want for a given BatchRequest and after the batch execution link the failing requests back to that information. Something along these lines:

var batch = context.NewBatch();

// Sample on how to track additional information for a batch request
Dictionary<Guid, int> deletedListItemIds = new();

for (int i = 1; i <= 150; i++)
{
    await myList.Items.DeleteByIdBatchAsync(batch, i);
    deletedListItemIds.Add(batch.Requests.Last().Value.Id, i);
}

// Execute the batch without throwing an error, should get a result collection back
var batchResponse = await context.ExecuteAsync(batch, false);                

// Find the corresponding batch requests
foreach (var errorResult in errorResults)
{
    var failedListItemIdDelete = deletedListItemIds.FirstOrDefault(p=> p.Key == errorResult.BatchRequestId).Value;
}

jansenbe added a commit that referenced this issue Feb 13, 2024
…ding `BatchResponse` to enable more advanced batch handling scenarios #1374
@jansenbe
Copy link
Contributor

jansenbe commented Feb 13, 2024

@wizofaus : just pushed the change that enables this. Closing this issue now

@wizofaus
Copy link
Author

wizofaus commented Mar 14, 2024

I can see this Id is public now, but just to confirm, I have to rely on knowing the order of the request in the current batch to match them with my input data? (i.e. I can't just associate my own data with each request).
Also, I have to grab those ids before executing the batch - they're not available after doing so?

And I note that BatchResult constructor is still internal, but I need to call it for mocking purposes. Which is only possible currently via reflection - which of course caused errors on running those tests now that you've added a new parameter!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: framework ⚙ Changes in the SDK core framework code question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants