OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.82k stars 6.58k forks source link

[BUG][Elm] Generation crashes with Exception: Property type is missing from getVars #13571

Open Erudition opened 2 years ago

Erudition commented 2 years ago

Bug Report Checklist

Description

The elm generator produces partial output and broken code before failing with this error:

  Exception: Property type is missing from getVars
    at org.openapitools.codegen.DefaultGenerator.processOperation(DefaultGenerator.java:1187)
    at org.openapitools.codegen.DefaultGenerator.processPaths(DefaultGenerator.java:1078)
    at org.openapitools.codegen.DefaultGenerator.generateApis(DefaultGenerator.java:580)
    at org.openapitools.codegen.DefaultGenerator.generate(DefaultGenerator.java:915)
    at org.openapitools.codegen.cmd.Generate.execute(Generate.java:465)
    at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
    at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)
Caused by: java.lang.RuntimeException: Property type is missing from getVars
    at org.openapitools.codegen.DefaultCodegen.addRequiredVarsMap(DefaultCodegen.java:7319)
    at org.openapitools.codegen.DefaultCodegen.addVarsRequiredVarsAdditionalProps(DefaultCodegen.java:7354)
    at org.openapitools.codegen.DefaultCodegen.fromParameter(DefaultCodegen.java:4972)
    at org.openapitools.codegen.DefaultCodegen.fromOperation(DefaultCodegen.java:4394)
    at org.openapitools.codegen.DefaultGenerator.processOperation(DefaultGenerator.java:1155)
    ... 6 more
openapi-generator version

6.2.0 (latest via npm)

OpenAPI declaration file content or url

https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json

Generation Details
Steps to reproduce
  1. generate -i "https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json" -g elm -o elmStripeAPI
cyangle commented 2 years ago

I got the same error when generating crystal client for stripe api. It seems like 2 get operations are interfering each other with required params.

Here's a minimal spec file that reproduces this error with latest master branch generating crystal client. The same spec works with v6.0.1.

It seems like this bug was introduced by #13117. @spacether

openapi: 3.0.0
info:
  description: >-
    This spec is mainly for testing Petstore server and contains fake endpoints,
    models. Please do not use this for any other purpose. Special characters: "
    \
  version: 1.0.0
  title: OpenAPI Petstore
  license:
    name: Apache-2.0
    url: "https://www.apache.org/licenses/LICENSE-2.0.html"
tags:
  - name: fake
paths:
  /fake:
    get:
      tags:
        - fake
      operationId: fake
      parameters:
        - name: limit
          in: query
          required: false
          schema:
            type: integer
          style: form
        - name: scope
          in: query
          required: true
          style: deepObject
          explode: true
          schema:
            $ref: "#/components/schemas/scope_param"
      responses:
        "200":
          description: The instance started successfully
          content:
            application/json:
              schema:
                type: object
                additionalProperties: string
  /fake2:
    get:
      tags:
        - fake
      operationId: fake2
      parameters:
        - name: scope
          in: query
          required: true
          style: deepObject
          explode: true
          schema:
            $ref: "#/components/schemas/scope_param"
      responses:
        "200":
          description: The instance started successfully
          content:
            application/json:
              schema:
                type: object
                additionalProperties: string
servers:
  - url: https://localhost:8080/{version}
    description: The local server
    variables:
      version:
        enum:
          - "v1"
          - "v2"
        default: "v2"
  - url: https://127.0.0.1/no_variable
    description: The local server without variables
components:
  schemas:
    scope_param:
      type: object
      title: scope_param
      properties:
        type:
          enum: ["account", "user"]
          type: "string"
        user:
          maxLength: 5000,
          type: "string"
      required: ["type"]

And the error I got is this:

Exception in thread "main" java.lang.RuntimeException: Could not process operation:
  Tag: class Tag {
    name: fake
    description: null
    externalDocs: null
}
  Operation: fake2
  Resource: get /fake2
  Schemas: {scope_param=class ObjectSchema {
    class Schema {
        type: object
        format: null
        $ref: null
        description: null
        title: scope_param
        multipleOf: null
        maximum: null
        exclusiveMaximum: null
        minimum: null
        exclusiveMinimum: null
        maxLength: null
        minLength: null
        pattern: null
        maxItems: null
        minItems: null
        uniqueItems: null
        maxProperties: null
        minProperties: null
        required: [type]
        not: null
        properties: {type=class StringSchema {
            class Schema {
                type: string
                format: null
                $ref: null
                description: null
                title: null
                multipleOf: null
                maximum: null
                exclusiveMaximum: null
                minimum: null
                exclusiveMinimum: null
                maxLength: null
                minLength: null
                pattern: null
                maxItems: null
                minItems: null
                uniqueItems: null
                maxProperties: null
                minProperties: null
                required: null
                not: null
                properties: null
                additionalProperties: null
                nullable: null
                readOnly: null
                writeOnly: null
                example: null
                externalDocs: null
                deprecated: null
                discriminator: null
                xml: null
            }
        }, user=class StringSchema {
            class Schema {
                type: string
                format: null
                $ref: null
                description: null
                title: null
                multipleOf: null
                maximum: null
                exclusiveMaximum: null
                minimum: null
                exclusiveMinimum: null
                maxLength: null
                minLength: null
                pattern: null
                maxItems: null
                minItems: null
                uniqueItems: null
                maxProperties: null
                minProperties: null
                required: null
                not: null
                properties: null
                additionalProperties: null
                nullable: null
                readOnly: null
                writeOnly: null
                example: null
                externalDocs: null
                deprecated: null
                discriminator: null
                xml: null
            }
        }}
        additionalProperties: null
        nullable: null
        readOnly: null
        writeOnly: null
        example: null
        externalDocs: null
        deprecated: null
        discriminator: null
        xml: null
    }
}}
  Exception: Property type is missing from getVars
        at org.openapitools.codegen.DefaultGenerator.processOperation(DefaultGenerator.java:1187)
        at org.openapitools.codegen.DefaultGenerator.processPaths(DefaultGenerator.java:1078)
        at org.openapitools.codegen.DefaultGenerator.generateApis(DefaultGenerator.java:580)
        at org.openapitools.codegen.DefaultGenerator.generate(DefaultGenerator.java:915)
        at org.openapitools.codegen.cmd.Generate.execute(Generate.java:465)
        at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
        at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)
Caused by: java.lang.RuntimeException: Property type is missing from getVars
        at org.openapitools.codegen.DefaultCodegen.addRequiredVarsMap(DefaultCodegen.java:7319)
        at org.openapitools.codegen.DefaultCodegen.addVarsRequiredVarsAdditionalProps(DefaultCodegen.java:7354)
        at org.openapitools.codegen.DefaultCodegen.fromParameter(DefaultCodegen.java:4972)
        at org.openapitools.codegen.DefaultCodegen.fromOperation(DefaultCodegen.java:4394)
        at org.openapitools.codegen.DefaultGenerator.processOperation(DefaultGenerator.java:1155)
        ... 6 more
spacether commented 2 years ago

Thank you for reporting this bug @Erudition and @cyangle this is happening because DefaultCodegen is modifying the codegenProperty.baseName which is used used to store the schema property name from the spec in an unmodifed state. This line: https://github.com/OpenAPITools/openapi-generator/blame/master/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java#L5080 is mutating the baseName so that the properties.vars have the names:

And the code in https://github.com/OpenAPITools/openapi-generator/pull/13117 is looking for unmodified baseNames. Also one is unable to run fromProperty to make a map from spec property name to current baseName because this baseName mutation happens outside of fromProperty, in fromParameter.

@wing328 why was that change made in https://github.com/OpenAPITools/openapi-generator/pull/8563? Can the code at that location be adjusted to modify another property instead of baseName, like name? If the baseName is not modified, these specs will run as-is.

It looks like this code that modifies baseName was originally added in: https://github.com/OpenAPITools/openapi-generator/pull/8563 [java native][dotnetcore] Implement QueryParameter deepObject style

cyangle commented 2 years ago

The implementation in #8563 probably doesn't work with nested json objects.

I think a model flattener is better than the current implementation.

Erudition commented 2 years ago

Just tried @cyangle 's workaround, it builds now! Alas, my generated code still has a thousand compile errors :(

wing328 commented 2 years ago

Agreed that the baseName of the property shouldn't be updated.

@Reinhard-PTV (author of #8563), for the following line:

                                property.baseName = codegenParameter.baseName + "[" + entry.getKey() + "]";

ref: https://github.com/OpenAPITools/openapi-generator/pull/8563/files#diff-3a138675e8cb40943bcb00feb46edd6f6ee5c5306c29cc19f02c845a299c8658R4452

can we store the value in vendorExtensions (e.g. x-deep-object-name) instead?

jawad-r3 commented 2 years ago

Guys, Is there any workaround to this? I need to generate some Apex clients for Stripe API.

Erudition commented 1 year ago

Guys, Is there any workaround to this? I need to generate some Apex clients for Stripe API.

See the messages before yours and you will see that yes, there is a workaround, and yes, I tried it and it works.

But alas, we're still a long way from a usable Stripe API it seems. The generated code doesn't compile, and it's not trivial to fix, due to many remaining bugs in the Elm generator.

I fixed hundreds of errors and gave up - they just keep coming. Distinct items named exactly the same, lists not closed, parameters missing altogether because their type is unsupported... the generator may be good as-is for simple APIs, but the Stripe API is too complex and uses too many OpenAPI features that are still broken in the Elm generator...

recryptoonline commented 1 year ago

reproduced here as well