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

[BUG][csharp-netcore]Unhandled exception when response is not 200 when using RestSharp #9966

Open
5 of 6 tasks
kaburke opened this issue Jul 17, 2021 · 0 comments
Open
5 of 6 tasks

Comments

@kaburke
Copy link

kaburke commented Jul 17, 2021

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

The generated code calls RestSharp using generic methods that attempt to deserialize the response into a specified model. However, the model passed to the method is always the model defined in the 200 response of the OAS specification. Therefore, if another response is returned, even if it is expected and defined in the OAS file, the code throws an unhandled exception.

The expected result is an ApiException containing the data returned in the response from the Web API.

openapi-generator version

Versions 5.1.1, 5.2.0, 5.2.1, 5.2.2 and 6.0.0, including latest snapshots of each have been tried.

OpenAPI declaration file content or url

Consider the following OAS snippet, noting that two responses are expected and defined:

  /file/search/{SearchRoot}:
    get:
      operationId: SearchFileSystem
      description: Search files and directories. Will search in all subdirectories.
      parameters:
        - name: SearchRoot
          in: path
          required: true
          schema:
            type: string
        - name: q
          in: query
          required: true
          description: Search query
          schema:
            type: string
      responses:
        200:
          description: The search completed.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FileSystemItemInfo'
        403:
          $ref: '#/components/responses/Unauthorized'
      security:
        - bearerAuth: []
Generation Details

Using the given command to generate client code ():
java -jar openapi-generator-cli-6.0.0-20210712.095051-16.jar generate -i oas.yaml -o .\generated -g csharp-netcore --additional-properties=netCoreProjectFile=true,targetFramework=net5.0 --global-property modelTests=false --global-property apiTests=false

Steps to reproduce

The client is invoked with:

try
{
    DefaultApi m_sgcSSClient = new DefaultApi();
    List<FileSystemItemInfo> lstResults = await m_sgcSSClient.SearchFileSystemAsync("", "cubes");
}
catch (ApiException ex)
{
    // handle the exception
}

Note that the method called requires a bearer token, and that none was set. This is to force a 403 response from the Web API.
The expected result is an ApiException containing the data returned in the 403 response from the Web API.
The actual result is an unhandled exception thrown in the custom deserializer of the generated client. This happens because the WebAPI is called in the generated code using the following RestSharp call:

    response = await client.ExecuteAsync<T>(req, cancellationToken).ConfigureAwait(false);

where T is FileSystemItemInfo. Thus, RestSharp attempts to deserialize the response to an object of type T regardless of the response code of the call, even though type T is only valid if the response code is 200.

Related issues/PRs

It seems that the same issue was found with the HttpClient library, and was fixed:
#9389

Suggest a fix

The generated client should not attempt deserialization to the model type until the response code is verified, and the correct model is determined. One possible solution is to call RestSharp using the non-generic call:

    IRestResponse response = await client.ExecuteAsync(req, cancellationToken).ConfigureAwait(false);

and then call the custom deserialzor after checking response.StatusCode.

The relevant lines are in the `ApiCLient.mustache' file, on lines 492 and 607.

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

No branches or pull requests

1 participant