Skip to content

[BUG] [cpp-httplib-server] Throw exception if optional property not present in json payload #23991

@stefanwitkowskiwmb

Description

@stefanwitkowskiwmb

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator?
  • 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?
Description

Many client generators omit optional properties (those not listed in required) when they are unset, which is spec-compliant — the JSON node for these properties is then absent. In this case the deserialization code generated by the cpp-httplib-server generator crashes instead of handling the missing node.

openapi-generator version

v7.23.0

OpenAPI declaration file content or url
openapi: "3.0.0"
info:
  title: Enum Bug Reproduction
  version: "1.0.0"


paths:
  /example:
    post:
      operationId: postExample
      parameters:
        - in: query
          name: status
          schema:
            $ref: '#/components/schemas/PostBody'
      responses:
        '200':
          description: OK

components:
  schemas:
    PostBody:
      type: object
      properties:
        status:
          type: string
        data:
          type: string
      required:
        - status
Generation Details

generation script:

#!/usr/bin/env pwsh
param()

$ErrorActionPreference = 'Stop'

$SpecDir = Resolve-Path (Join-Path $PSScriptRoot 'openapi')
$OutputDir = Resolve-Path (Join-Path $PSScriptRoot 'source')

Write-Output "[generate-models] Spec:   $SpecDir\openapi.yaml"
Write-Output "[generate-models] Output: $OutputDir"

Write-Output "[generate-models] Using Docker..."
docker run --rm `
    -v "${SpecDir}:/spec" `
    -v "${OutputDir}:/output" `
    "openapitools/openapi-generator-cli:latest" generate `
    -i /spec/openapi.yaml `
    -g cpp-httplib-server `
    -o /output `
    --global-property 'models,modelDocs=false,modelTests=false' `
    --additional-properties='enumClassPrefix=true'

if ($LASTEXITCODE -ne 0) {
    throw "[generate-models] ERROR: Generation failed."
}

Write-Output "[generate-models] Done."
Steps to reproduce
    std::string jsonString = "{\"status\":\"accepted\"}";
    nlohmann::json jsonObject = nlohmann::json::parse(jsonString);
    models::PostBody deserializedBody = jsonObject.get<models::PostBody>();
Related issues/PRs
Suggest a fix

Probably instead of NLOHMANN_DEFINE_TYPE_INTRUSIVE it would be necessary to implement explicit friend methods. maybe something like this:

    friend void to_json(nlohmann::json& j, const {{vendorExtensions.modelClassName}}& o)
    {
        {{#vars}}j["{{baseName}}"] = o.{{nameInCamelCase}};
        {{/vars}}
    }

    friend void from_json(const nlohmann::json& j, {{vendorExtensions.modelClassName}}& o)
    {
        {{#requiredVars}}j.at("{{baseName}}").get_to(o.{{nameInCamelCase}});
        {{/requiredVars}}
        {{#optionalVars}}if (j.contains("{{baseName}}") && !j.at("{{baseName}}").is_null())
        {
            j.at("{{baseName}}").get_to(o.{{nameInCamelCase}});
        }
        {{/optionalVars}}
    }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions