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

[PHP] Bug deserialize default responses as a Model #7544

Open
ymilin opened this issue Feb 1, 2018 · 3 comments · May be fixed by #7968
Open

[PHP] Bug deserialize default responses as a Model #7544

ymilin opened this issue Feb 1, 2018 · 3 comments · May be fixed by #7968

Comments

@ymilin
Copy link

ymilin commented Feb 1, 2018

Description

I'm generating clients that make use of default responses for other HTTP codes (implying an error). It's defined as a Model (code, message) in definitions in the swagger file.

...
  responses:
    '200':
      description: pet response
      schema:
        type: array
        items:
          $ref: '#/definitions/Pet'
    default:
      description: error payload
      schema:
        $ref: '#/definitions/ErrorModel'
...

After generating the client API with swagger-codegen, when catching an ApiException, the deserialized response object ApiException::responseObject is empty (it is an an instance of ErrorModel as expected, but with no content).

Swagger-codegen version

2.3.0

Swagger declaration file content or url

gist: minimal swagger.json example

Command line used for generation
java -jar bin/swagger-codegen-cli.jar generate -i swagger.json \
  -l php \
  -o build/ \
  --git-user-id "vendor" \
  --git-repo-id "ws-clients" \
  -DpackagePath=.,srcBasePath=lib,variableNamingConvention=camelCase,invokerPackage="MyCie\\Service",apiTests=false,apiDocs=false,modelTests=false,modelDocs=false
Steps to reproduce

With the generated client:

  • try to make a request for a non-existing pet
  • Expect $e->getResponseObject() to be a fully hydrated instance of ErrorModel
  • Got an empty instance of ErrorModel instead
$petApi = new PetApi();

try {
  $pet = $api->getPetById(123);
  ...
} catch (ApiException $e) {
  $errorModel = $e->getResponseObject();
  print_r($errorModel); // empty ErrorModel
}
Suggest a fix/enhancement

I checked the generated code and the bug seem to be located in the catch part of the {{operationId}}WithHttpInfo methods:

try {
    ...
} catch (ApiException $e) {
    switch ($e->getCode()) {
        case 200:
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(),
                '\MyCie\Service\Model\Pet',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);
            break;
        default:
            $data = ObjectSerializer::deserialize(
                $e->getResponseBody(), // <-- works with json_decode($e->getResponseBody())
                '\MyCie\Service\Model\ErrorModel',
                $e->getResponseHeaders()
            );
            $e->setResponseObject($data);
            break;
    }
    throw $e;
}

We can see that there is a specific test for this in the try part of same function in the api.mustache file, line 164

$content = $responseBody->getContents();
if ($returnType !== 'string') {
$content = json_decode($content);
}

So a possible fix would be doing something similar when deserializing for ApiException objects.

I can work on a PR for this, as I really need it, but I have no experience with mustache templates and will not be able to test edge cases.

So I would need help for testing my PR.

@ymilin ymilin changed the title [PHP] Bug deserialize error as a Model [PHP] Bug deserialize default responses as a Model Feb 1, 2018
@ymilin ymilin closed this as completed Apr 3, 2018
@ymilin ymilin reopened this Apr 3, 2018
@ymilin ymilin linked a pull request Apr 4, 2018 that will close this issue
4 tasks
@kamynina
Copy link

kamynina commented Jul 1, 2018

any updates?

@HugoMario
Copy link
Contributor

thanks @ymilin , i'll take a time this week to review your PR.

@ymilin
Copy link
Author

ymilin commented Jul 1, 2018

Hi @kamynina,

I did try and submit a PR for this issue here

Code review (thanks @wing328) showed that my fix is causing issues with primitive type responses and I promised to spend more time on it for a definitive fix.

Since then, I couldn't find more time to come back to it but I'm pretty confident I will be able to somewhere this summer 🤷‍♂️

@HugoMario ,
Thanks, if you have anything to add to the reviews on my PR, I'll try to reply as quickly as I can.

Edit:
As a temporary fix in PHP code using the generated clients, I call ObjectSerializer::deserialize inside a catch block on $e->getResponseHeaders()

try {
    ...
} catch (ApiException $e) {
    $errorModel = ObjectSerializer::deserialize(
        json_decode($e->getResponseBody()),
        \Foo\ErrorModel::class,
        $e->getResponseHeaders()
    );

    // $errorModel is an instance of \Foo\ErrorModel
}

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

Successfully merging a pull request may close this issue.

3 participants