microsoft / microsoft/kiota

IResponseHandler set through RequestInformation.SetResponseHandler is ignored

Open
#7,017 0 comments 0 reactions 0 assignees View on GitHub
Csharp type:bug
Dominant language
C#
Stars
3.8k
Forks
333
Avg merge
16h 29m
Merged PRs (30d)
116

Description

### What are you generating using Kiota, clients or plugins?

API Client/SDK

### In what context or format are you using Kiota?

Windows executable

### Client library/SDK language

Csharp

### Describe the bug

The `Microsoft.Kiota.Abstractions.RequestInformation` class has a `SetResponseHandler` method that sets an `IResponseHandler` instance and sets the `ResponseHandlerOption` to the request options.

As far as I understand, you should use code like this to use it:

```csharp
PackagesRequestBuilder packagesRequestBuilder = vbusOrg.Packages;
RequestInformation packagesRequestInfo = packagesRequestBuilder.ToGetRequestInformation();
packagesRequestInfo.SetResponseHandler(adapter); // adapter implements IResponseHandler

var packageListResponse = await packagesRequestBuilder.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.PackageType = GetPackage_typeQueryParameterType.Nuget;
requestConfiguration.QueryParameters.PerPage = 5;
});
```

But the problem is that the `GetAsync` method is generated with the following content:

```csharp
public async Task?> GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default)
{
var requestInfo = ToGetRequestInformation(requestConfiguration);
var errorMapping = new Dictionary>
{
{ "401", global::GitHub.Models.BasicError.CreateFromDiscriminatorValue },
{ "403", global::GitHub.Models.BasicError.CreateFromDiscriminatorValue },
};
var collectionResult = await RequestAdapter.SendCollectionAsync(requestInfo, global::GitHub.Models.Package.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
return collectionResult?.AsList();
}
```

As seen, the method generates a new RequestInformation, and I cannot see any methods that actually allow the one generated *before* the call to `GetAsync` to be passed into the method.

This means that it (as far as I can see) in practice is impossible to use your own `IResponseHandler` implementation.

### Expected behavior

When setting a custom `IResponseHandler` instance to the `RequestInformation` instance, I would expect it to be utilized.

### How to reproduce

1. Generate an API client of any kind (I'm using github api).
2. Create a class implementing `IResponseHandler`.
3. Set a breakpoint in the `HandleResponseAsync` method.
4. Execute the `GetAsync` code as shown in bug description.
5. Notice that tghe breakpoint from (3) is *not* hit

### Open API description file

_No response_

### Kiota Version

1.28.0+57130b1b1db3bc5c060498682f41e20c8ae089f2

### Latest Kiota version known to work for scenario above?(Not required)

_No response_

### Known Workarounds

_No response_

### Configuration

- OS: Windows 11 and Linux Mint 22.2 (based on Ubuntu 24.04)
- Architecture x64 (both)

### Debug output

Click to expand log

```

```

### Other information

As far as I can see, the issue is that the `RequestInformation` instance generated before the call to `GetAsync` is simply not passed into the `GetAsync` method or the `RequestBuilder` instance in any way.

I see some ways of resolving this:

1. Create an overload of all the `Send*` methods that pass a `RequestInformation` instanse to be used instead of creating a new one.
2. Add an optional `RequestInformation` parameter to all the `Send*` methods and use that instead of creating a new one.
4. Add a `RequestInformation` field to the `RequestBuilder` class and use that if set instead of creating a new one.
5. Create an event handler on `RequestBuilder` class that can be subscribed to in order to provide the `RequestInformation`.

Note that these would need to be done on the `IRequestAdapter` interface also as the `RequestBuilder` calls further to the `RequestAdapter` member.

Contributor guide

Open the contributing guide

Research direction

Start with the generated GetAsync entry point and trace its RequestInformation into IRequestAdapter.Send* methods, then inspect RequestInformation.SetResponseHandler and the RequestBuilder flow. Reproduce the issue with a custom IResponseHandler and confirm that the selected design allows the handler set on the request to be invoked.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend-api-design
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.