-
Notifications
You must be signed in to change notification settings - Fork 299
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 X openapi specification describes the results for the "delete a tweet" endpoint like this:
"/2/tweets/{id}" : {
"delete" : {
...
"summary" : "Delete Post",
"description" : "Deletes a specific Post by its ID, if owned by the authenticated user.",
"externalDocs" : {
"url" : "https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id"
},
"operationId" : "deletePosts",
"parameters" : [
{
"name" : "id",
"in" : "path",
"description" : "The ID of the Post to be deleted.",
"required" : true,
"schema" : {
"$ref" : "#/components/schemas/TweetId"
},
"style" : "simple"
}
],
"responses" : {
"200" : {
"description" : "The request has succeeded.",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/TweetDeleteResponse"
}
}
}
},
"default" : {
"description" : "The request has failed.",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/Error"
}
},
"application/problem+json" : {
"schema" : {
"$ref" : "#/components/schemas/Problem"
}
}
}
}
}
},
Note that the non-success result object depends on the content type of the response: for "application/json" it should be an "Error" class, for "application/problem+json" it should be a "Problem" class.
If I delete a random ID (that I am not allowed to delete), the raw response is:
{
"detail": "You are not authorized to delete this Tweet.",
"type": "about:blank",
"title": "Forbidden",
"status": 403
}
(found by extracting the response content with a BodyInspectionHandlerOption)
Those are the properties of the "Problem" class:
"Problem" : {
"type" : "object",
"description" : "An HTTP Problem Details object, as defined in IETF RFC 7807 (https://tools.ietf.org/html/rfc7807).",
"required" : [
"type",
"title"
],
"properties" : {
"detail" : {
"type" : "string"
},
"status" : {
"type" : "integer"
},
"title" : {
"type" : "string"
},
"type" : {
"type" : "string"
}
},
But in my code, I can catch only a meaningless exception, and you can see that it is an "Error" class without any details:
XbyOpenApi.Core.Client.Models.Error
HResult=0x80131500
Message=
Source=Microsoft.Kiota.Http.HttpClientLibrary
StackTrace:
at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.<ThrowIfFailedResponseAsync>d__30.MoveNext()
at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.<SendAsync>d__22`1.MoveNext()
at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.<SendAsync>d__22`1.MoveNext()
at XbyOpenApi.Core.Client.Two.Tweets.Item.ItemRequestBuilder.<DeleteAsync>d__12.MoveNext() in E:\Projekte\Github\XbyOpenApi\XbyOpenApi.Core\Client\Two\Tweets\Item\ItemRequestBuilder.cs:line 87
This exception was originally thrown at this call stack:
Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.ThrowIfFailedResponseAsync(System.Net.Http.HttpResponseMessage, System.Collections.Generic.Dictionary<string, Microsoft.Kiota.Abstractions.Serialization.ParsableFactory<Microsoft.Kiota.Abstractions.Serialization.IParsable>>, System.Diagnostics.Activity, System.Threading.CancellationToken)
Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.SendAsync<ModelType>(Microsoft.Kiota.Abstractions.RequestInformation, Microsoft.Kiota.Abstractions.Serialization.ParsableFactory<ModelType>, System.Collections.Generic.Dictionary<string, Microsoft.Kiota.Abstractions.Serialization.ParsableFactory<Microsoft.Kiota.Abstractions.Serialization.IParsable>>, System.Threading.CancellationToken)
Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.SendAsync<ModelType>(Microsoft.Kiota.Abstractions.RequestInformation, Microsoft.Kiota.Abstractions.Serialization.ParsableFactory<ModelType>, System.Collections.Generic.Dictionary<string, Microsoft.Kiota.Abstractions.Serialization.ParsableFactory<Microsoft.Kiota.Abstractions.Serialization.IParsable>>, System.Threading.CancellationToken)
XbyOpenApi.Core.Client.Two.Tweets.Item.ItemRequestBuilder.DeleteAsync(System.Action<Microsoft.Kiota.Abstractions.RequestConfiguration<Microsoft.Kiota.Abstractions.DefaultQueryParameters>>, System.Threading.CancellationToken) in ItemRequestBuilder.cs
So the result is mapped to the wrong class.
This error is thrown from HttpClientRequestAdapter.ThrowIfFailedResponseAsync where only a status code mapping is done.
I don't know whether a content type mapping should also happen there or in the generated client code.
In the generated client code, the method looks like this: only the class "Error" is handled:
public async Task<global::XbyOpenApi.Core.Client.Models.TweetDeleteResponse> DeleteAsync(Action<RequestConfiguration<DefaultQueryParameters>> requestConfiguration = default, CancellationToken cancellationToken = default)
{
var requestInfo = ToDeleteRequestInformation(requestConfiguration);
var errorMapping = new Dictionary<string, ParsableFactory<IParsable>>
{
{ "XXX", global::XbyOpenApi.Core.Client.Models.Error.CreateFromDiscriminatorValue },
};
return await RequestAdapter.SendAsync<global::XbyOpenApi.Core.Client.Models.TweetDeleteResponse>(requestInfo, global::XbyOpenApi.Core.Client.Models.TweetDeleteResponse.CreateFromDiscriminatorValue, errorMapping, cancellationToken).ConfigureAwait(false);
}
I think this is actually a bug on the X side, because the doc at https://docs.x.com/x-api/posts/delete-post and the OpenAPI description don't match - according to the doc it should even be an array of "Problems".
I even managed to create a reponse like this that does not appear in the api description:
{
"errors": [
{
"parameters": {
"id": [
"1261326399320715264,1278347468690915330"
]
},
"message": "The `id` query parameter value [1261326399320715264,1278347468690915330] is not valid"
}
],
"title": "Invalid Request",
"detail": "One or more parameters to your request was invalid.",
"type": "https://api.twitter.com/2/problems/invalid-request"
}
Expected behavior
What do you think? Would it be possible in the Kiota generated client to create a response discriminator based on the content type?
I think this is the RFC that defines this behavior: https://datatracker.ietf.org/doc/html/rfc7807
Unfortunately, even if you handle this perfectly, it will not work because of X "problems".
How to reproduce
Sorry, as you need a (free) X account, you cannot reproduce this probably
Open API description file
https://api.twitter.com/2/openapi.json
Kiota Version
1.30.0
Latest Kiota version known to work for scenario above?(Not required)
No response
Known Workarounds
No response
Configuration
No response
Debug output
Click to expand log
```</details>
### Other information
_No response_
Metadata
Metadata
Assignees
Labels
Type
Projects
Status