-
Notifications
You must be signed in to change notification settings - Fork 294
Closed
Labels
WIPenhancementNew feature or requestNew feature or requestgeneratorIssues or improvements relater to generation capabilities.Issues or improvements relater to generation capabilities.
Milestone
Description
Our server returns HTTP 304 (Not Modified) without a response body when the incoming fingerprint in the If-None-Match header matches the stored version. This enables clients to poll for changes without receiving a response body, unless it has changed since it was last fetched.
Status 304 is described in the OAS document, but Kiota throws an ApiException saying the error isn't mapped:
Microsoft.Kiota.Abstractions.ApiException: The server returned an unexpected status code and no error factory is registered for this code: 304
OAS fragment:
{
"paths": {
"/api/people": {
"get": {
"tags": [
"people"
],
"summary": "Retrieves a collection of people.",
"operationId": "getPersonCollection",
"responses": {
"200": {
"description": "Successfully returns the found people, or an empty array if none were found.",
"headers": {
"ETag": {
"description": "A fingerprint of the HTTP response, which can be used in an If-None-Match header to only fetch changes.",
"required": true,
"schema": {
"type": "string"
}
}
},
"content": {
"application/vnd.api+json": {
"schema": {
"$ref": "#/components/schemas/personCollectionResponseDocument"
}
}
}
},
"400": {
"description": "The query string is invalid.",
"content": {
"application/vnd.api+json": {
"schema": {
"$ref": "#/components/schemas/errorResponseDocument"
}
}
}
},
"304": {
"description": "The fingerprint of the HTTP response matches one of the ETags from the incoming If_None_Match header.",
"headers": {
"ETag": {
"description": "A fingerprint of the HTTP response, which can be used in an If-None-Match header to only fetch changes.",
"required": true,
"schema": {
"type": "string"
}
}
}
}
}
}
}
}
}Generated C# code:
namespace GeneratedClient.Api.People {
public class PeopleRequestBuilder : BaseRequestBuilder {
/// <summary>
/// Retrieves a collection of people.
/// </summary>
/// <param name="cancellationToken">Cancellation token to use when cancelling requests</param>
/// <param name="requestConfiguration">Configuration for the request such as headers, query parameters, and middleware options.</param>
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER
#nullable enable
public async Task<PersonCollectionResponseDocument?> GetAsync(Action<RequestConfiguration<PeopleRequestBuilderGetQueryParameters>>? requestConfiguration = default, CancellationToken cancellationToken = default) {
#nullable restore
#else
public async Task<PersonCollectionResponseDocument> GetAsync(Action<RequestConfiguration<PeopleRequestBuilderGetQueryParameters>> requestConfiguration = default, CancellationToken cancellationToken = default) {
#endif
var requestInfo = ToGetRequestInformation(requestConfiguration);
var errorMapping = new Dictionary<string, ParsableFactory<IParsable>> {
{"400", ErrorResponseDocument.CreateFromDiscriminatorValue},
};
return await RequestAdapter.SendAsync<PersonCollectionResponseDocument>(requestInfo, PersonCollectionResponseDocument.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
}
}
}To work around this, we need to catch an exception to detect HTTP 304 is being returned:
var headerInspector = new HeadersInspectionHandlerOption
{
InspectResponseHeaders = true
};
PersonCollectionResponseDocument? getResponse1 = await client.Api.People.GetAsync(
configuration => configuration.Options.Add(headerInspector));
string eTag = headerInspector.ResponseHeaders["ETag"].Single();
try
{
PersonCollectionResponseDocument? getResponse2 = await client.Api.People.GetAsync(
configuration => configuration.Headers.Add("If-None-Match", eTag));
}
catch (ApiException exception) when (exception.ResponseStatusCode == (int)HttpStatusCode.NotModified)
{
Console.WriteLine("The HTTP response hasn't changed, so no response body was returned.");
}This looks like a bug to me. In KiotaBuilder.cs, I found the following line:
private static readonly HashSet<string> noContentStatusCodes = new(StringComparer.OrdinalIgnoreCase) { "201", "202", "204", "205" };Should that just be changed to include 304?
Metadata
Metadata
Assignees
Labels
WIPenhancementNew feature or requestNew feature or requestgeneratorIssues or improvements relater to generation capabilities.Issues or improvements relater to generation capabilities.
Type
Projects
Status
Done ✔️