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

[csharp-netcore][httpclient] Issues managing error statuses #9389

Merged
merged 9 commits into from
May 6, 2021
Merged

[csharp-netcore][httpclient] Issues managing error statuses #9389

merged 9 commits into from
May 6, 2021

Conversation

lucamazzanti
Copy link
Contributor

Comparing the behavior with Restsharp I found an issue.

  1. When giving a bad status code 400 or higher with a content, it throws an exception trying to deserialize the type T.
  2. When something goes wrong in the non async part, it thorws an AggregateException containing the ApiException, this is not expexted.
  3. The rawContent contains bad data the class name of the stream printed not the content.

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package 
    ./bin/generate-samples.sh
    ./bin/utils/export_docs_generators.sh
    
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    For Windows users, please run the script in Git BASH.
  • File the PR against the correct branch: master, 5.1.x, 6.0.x
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@Blackclaws

@wing328
Copy link
Member

wing328 commented May 4, 2021

@lucamazzanti thanks for the PR. Can you please also update the samples so that the CI can verify the change?

@lucamazzanti
Copy link
Contributor Author

Sorry now is completely done.

@wing328
Copy link
Member

wing328 commented May 4, 2021

Suggestion: what about adding a test or 2 with GetPetById on ID that doesn't exist (e.g. 99999) to trigger an exception (404) in https://github.com/OpenAPITools/openapi-generator/blob/master/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTests.cs ?

@lucamazzanti
Copy link
Contributor Author

I'll do it right now

@lucamazzanti
Copy link
Contributor Author

I added two samples to test the ApiException in case of 404, one with HttpInfo with the ExceptionFactory disabled to read the result, one simple that throws ApiException. I tried to mantain the same code sintax.

Then, to test all the basic features, I rewritten for my company the test class, adding more tests on the not async part etc, ...
I added it as PetApiTestV2, and is to delete before closing the task, but take a look maybe we can refactor the csharp tests the same way or similar.

EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6AC7DED5-0F52-4187-9BC1-74437AAEE42D}
EndGlobalSection
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm....why there are changes to this file? Did you open this solution with VS 16?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VS 15 is Visual Studio 2017
VS 16 is Visual Studio 2019
I opened it with the latest one patch of 2019.
But the commit after i rolledback it running the scripts.

@Blackclaws
Copy link
Contributor

I'd say remove the GetAwaiter.GetResult and just make the methods async. The reason they weren't made async originally is because they were still being used by the RestSharp code. As this now lives inside its own library folder we can just go ahead and turn the deserializer into async methods which should solve the issue with your aggregate exceptions

@wing328
Copy link
Member

wing328 commented May 5, 2021

Appveyor CI failed with the following error messages (partial):

----- Inner Stack Trace -----
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
  Skipped Org.OpenAPITools.Test.Api.PetApiTests.UploadFileAsync_UploadFileUsingFormParameters_UpdatesTheFields [1 ms]
[xUnit.net 00:00:22.16]     Org.OpenAPITools.Test.Api.PetApiTests.AddPet_GivenExistentId_UpdateThePet [FAIL]
  Failed Org.OpenAPITools.Test.Api.PetApiTests.AddPet_GivenExistentId_UpdateThePet [1 ms]
  Error Message:
   System.Net.Http.HttpRequestException : No connection could be made because the target machine actively refused it.
---- System.Net.Sockets.SocketException : No connection could be made because the target machine actively refused it.
  Stack Trace:
     at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Org.OpenAPITools.Client.ApiClient.ExecAsync[T](HttpRequestMessage req, IReadableConfiguration configuration, CancellationToken cancellationToken) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Client\ApiClient.cs:line 505
   at Org.OpenAPITools.Client.ApiClient.Exec[T](HttpRequestMessage req, IReadableConfiguration configuration) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Client\ApiClient.cs:line 447
   at Org.OpenAPITools.Client.ApiClient.Post[T](String path, RequestOptions options, IReadableConfiguration configuration) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Client\ApiClient.cs:line 663
   at Org.OpenAPITools.Api.PetApi.AddPetWithHttpInfo(Pet pet) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Api\PetApi.cs:line 724
   at Org.OpenAPITools.Api.PetApi.AddPet(Pet pet) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Api\PetApi.cs:line 666
   at Org.OpenAPITools.Test.Api.PetApiTests..ctor() in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools.Test\Api\PetApiTestsV2.cs:line 53
----- Inner Stack Trace -----
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
[xUnit.net 00:00:23.22]     Org.OpenAPITools.Test.Api.PetApiTests.GetPetByIdAsync_GivenNotExistentId_ThrowsApiException [FAIL]
[xUnit.net 00:00:24.25]     Org.OpenAPITools.Test.Api.PetApiTests.GetPetByIdWithHttpInfoAsync_GivenNotExistentId_ThrowsApiException [FAIL]
  Failed Org.OpenAPITools.Test.Api.PetApiTests.GetPetByIdAsync_GivenNotExistentId_ThrowsApiException [1 ms]
  Error Message:
   System.Net.Http.HttpRequestException : No connection could be made because the target machine actively refused it.
---- System.Net.Sockets.SocketException : No connection could be made because the target machine actively refused it.
  Stack Trace:
     at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Org.OpenAPITools.Client.ApiClient.ExecAsync[T](HttpRequestMessage req, IReadableConfiguration configuration, CancellationToken cancellationToken) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Client\ApiClient.cs:line 505
   at Org.OpenAPITools.Client.ApiClient.Exec[T](HttpRequestMessage req, IReadableConfiguration configuration) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Client\ApiClient.cs:line 447
   at Org.OpenAPITools.Client.ApiClient.Post[T](String path, RequestOptions options, IReadableConfiguration configuration) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Client\ApiClient.cs:line 663
   at Org.OpenAPITools.Api.PetApi.AddPetWithHttpInfo(Pet pet) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Api\PetApi.cs:line 724
   at Org.OpenAPITools.Api.PetApi.AddPet(Pet pet) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Api\PetApi.cs:line 666
   at Org.OpenAPITools.Test.Api.PetApiTests..ctor() in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools.Test\Api\PetApiTestsV2.cs:line 53
----- Inner Stack Trace -----
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
  Failed Org.OpenAPITools.Test.Api.PetApiTests.GetPetByIdWithHttpInfoAsync_GivenNotExistentId_ThrowsApiException [1 ms]
  Error Message:
   System.Net.Http.HttpRequestException : No connection could be made because the target machine actively refused it.
---- System.Net.Sockets.SocketException : No connection could be made because the target machine actively refused it.
  Stack Trace:
     at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Org.OpenAPITools.Client.ApiClient.ExecAsync[T](HttpRequestMessage req, IReadableConfiguration configuration, CancellationToken cancellationToken) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Client\ApiClient.cs:line 505
   at Org.OpenAPITools.Client.ApiClient.Exec[T](HttpRequestMessage req, IReadableConfiguration configuration) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Client\ApiClient.cs:line 447
   at Org.OpenAPITools.Client.ApiClient.Post[T](String path, RequestOptions options, IReadableConfiguration configuration) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Client\ApiClient.cs:line 663
   at Org.OpenAPITools.Api.PetApi.AddPetWithHttpInfo(Pet pet) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Api\PetApi.cs:line 724
   at Org.OpenAPITools.Api.PetApi.AddPet(Pet pet) in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools\Api\PetApi.cs:line 666
   at Org.OpenAPITools.Test.Api.PetApiTests..ctor() in C:\projects\openapi-generator\samples\client\petstore\csharp-netcore\OpenAPIClient-httpclient\src\Org.OpenAPITools.Test\Api\PetApiTestsV2.cs:line 53
----- Inner Stack Trace -----
   at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
Failed!  - Failed:    24, Passed:   318, Skipped:     5, Total:   347, Duration: 2 s - Org.OpenAPITools.Test.dll (netcoreapp3.0)

Ref: https://ci.appveyor.com/project/WilliamCheng/openapi-generator/builds/39001191

@lucamazzanti
Copy link
Contributor Author

lucamazzanti commented May 5, 2021

It seems a transient error during the integration test, the previous test was fine and nothing changes of iimpacting, the message also is clear. I will test it locally to ensure it is right to propagate an HttpRequestException or convert it to an ApiException, comparing to the RestApi version. On wich server they run? The public official one or during tests the global configuration changes to a temporary server?
I'll check also the drdrone git error.

@lucamazzanti
Copy link
Contributor Author

lucamazzanti commented May 5, 2021

I need help I probably don't understand the complete cycle of CI.
I launched the same tests on master and I have the same issue I had yesterday that moved me to create a new test class.

master branch

  • the deafult configuration in the test project point to a base path in http: http://petstore.swagger.io:80/v2
  • the setup for each integration tests tries to add a pet
  • there is a 302 redirection to the https address
  • the call receives an 405 error, because the web method is GET and not a POST
  • the deserializer tries to deserialize the supporting 302 message in Pet and generates error

this PR

  • I let unchanged everithing in the PetApiTests class so the behavior is similar, but not for the deserializer error part (for my fix)
  • I created a new class PetApiTestsV2 to test isolated and changed the basepath to https and it works
  • A few tests I tried to reproduce from the original class generate issues server side, so I decorated them to be ignored but invain

I see in the history that both appveyor configuration and test project are not changed recently so probably I'm missing something or the public server used for the integration tests changed forcing the https in those days.
Do you have an hint? I'm available also on Slack as @luca Mazzanti

@wing328
Copy link
Member

wing328 commented May 5, 2021

The public API server won't work with our tests. You will need to setup run your petstore server locally:

docker pull swaggerapi/petstore
docker run -d -e SWAGGER_HOST=http://petstore.swagger.io -e SWAGGER_BASE_PATH=/v2 -p 80:8080 swaggerapi/petstore

add add the following in the host table:

127.0.0.1    petstore.swagger.io

@lucamazzanti
Copy link
Contributor Author

@lucamazzanti
Copy link
Contributor Author

Thank you I found the two issues I put inside the test project and rolledback.

@wing328
Copy link
Member

wing328 commented May 5, 2021

Can you please undo changes to the following file?

	Changes not staged for commit:
426s
5618	  (use "git add <file>..." to update what will be committed)
426s
5619	  (use "git checkout -- <file>..." to discard changes in working directory)
426s
5620	
426s
5621		modified:   samples/server/petstore/aspnetcore-5.0/Org.OpenAPITools.sln

@lucamazzanti
Copy link
Contributor Author

Done

@wing328
Copy link
Member

wing328 commented May 6, 2021

👍

I'll merge it tomorrow before the v5.1.1 release if no one has further feedback on this PR.

@lucamazzanti
Copy link
Contributor Author

lucamazzanti commented May 6, 2021

Actually there is the class test PetApiTestsV2, maybe i can remove it and open a future PR to refactor the tests if useful.
Or you\we can just delete it.

@wing328
Copy link
Member

wing328 commented May 6, 2021

Actually there is the class test PetApiTestsV2, maybe i can remove it and open a future PR to refactor the tests if useful.

Sorry I don't understand. Why remove it? These are new tests that you added as part of this PR.

@lucamazzanti
Copy link
Contributor Author

lucamazzanti commented May 6, 2021

I don't know, maybe are not so similar to others or too much, and the class name is terrible. i don't want to add noise to the project. they were useful to me to certify the new client for our product.

@wing328
Copy link
Member

wing328 commented May 6, 2021

We can always improve the tests (naming, code style, etc) later with another PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants