RobinTail / express-zod-api

A Typescript library to help you get an API server up and running with I/O schema validation and custom middlewares in minutes.
https://ez.robintail.cz
MIT License
619 stars 30 forks source link

Default number range for `z.number()` causes `openapi-generator-cli generate` to fail #1849

Closed APTy closed 4 months ago

APTy commented 4 months ago

Description

This feels like it'd be a common issue, but there's very little information about it online, and the error message is not very clear.

It occurs when using z.number() in your types and then trying to generate HTML docs based on that.

  Exception: Character I is neither a decimal digit number, decimal point, nor "e" notation exponential mark.
    at org.openapitools.codegen.DefaultGenerator.processOperation(DefaultGenerator.java:1610)
    at org.openapitools.codegen.DefaultGenerator.processPaths(DefaultGenerator.java:1475)
    at org.openapitools.codegen.DefaultGenerator.generateApis(DefaultGenerator.java:677)
    at org.openapitools.codegen.DefaultGenerator.generate(DefaultGenerator.java:1307)
    at org.openapitools.codegen.cmd.Generate.execute(Generate.java:535)
    at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
    at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)
Caused by: java.lang.NumberFormatException: Character I is neither a decimal digit number, decimal point, nor "e" notation exponential mark.
    at java.base/java.math.BigDecimal.<init>(BigDecimal.java:608)
    at java.base/java.math.BigDecimal.<init>(BigDecimal.java:497)
    at java.base/java.math.BigDecimal.<init>(BigDecimal.java:903)
    at java.base/java.math.BigDecimal.valueOf(BigDecimal.java:1371)
    at org.openapitools.codegen.examples.ExampleGenerator.resolvePropertyToExample(ExampleGenerator.java:271)
    at org.openapitools.codegen.examples.ExampleGenerator.traverseSchemaProperties(ExampleGenerator.java:392)
    at org.openapitools.codegen.examples.ExampleGenerator.resolveModelToExample(ExampleGenerator.java:361)
    at org.openapitools.codegen.examples.ExampleGenerator.resolvePropertyToExample(ExampleGenerator.java:322)
    at org.openapitools.codegen.examples.ExampleGenerator.traverseSchemaProperties(ExampleGenerator.java:392)
    at org.openapitools.codegen.examples.ExampleGenerator.resolveModelToExample(ExampleGenerator.java:361)
    at org.openapitools.codegen.examples.ExampleGenerator.generate(ExampleGenerator.java:161)
    at org.openapitools.codegen.examples.ExampleGenerator.generateFromResponseSchema(ExampleGenerator.java:97)
    at org.openapitools.codegen.examples.ExampleGenerator.generateFromResponseSchema(ExampleGenerator.java:63)
    at org.openapitools.codegen.DefaultCodegen.fromOperation(DefaultCodegen.java:4702)
    at org.openapitools.codegen.DefaultGenerator.processOperation(DefaultGenerator.java:1578)
    ... 6 more

It seems related to https://github.com/OpenAPITools/openapi-generator/issues/12111. If that issue author's theory is correct, then maybe a solution would be for zod-express-api to use a default min/max of min(-1 * Number.MAX_VALUE / 10).max(Number.MAX_VALUE / 10).

Expected

I expected to be able to use a z.number() type and then generate HTML docs based on that.

Reproduction

  1. Create an API route that uses z.number() in one of the types
  2. Use new Documentation({ ... }).getSpecAsYaml() and write to api.yaml
  3. Generate HTML docs with openapi-generator-cli generate -g html -i api.yaml

Workarounds

Currently, using z.number().int() is a workaround if you don't need decimal precision. Or you can also set reasonable min().max() manually based on your use case.

EDIT: Probably using these workarounds is the correct thing to do until the problem is fixed in openapi-generator project.. it does seem like express-zod-api's behavior working as intended, and it's the other library that is broken.

Context

Appreciate your help!

RobinTail commented 4 months ago

@APTy , this is not a bug of express-zod-api, it's the bug of the third party software you're using.

The theory of the original issue's author is most likely correct, but it does not mean that express-zod-api should divide MAX_VALUE by 10. No, it means that the difference between min and max should not be assigned to a variable having the type that can not fit such number.

Please refer to the maintainer of openapi-generator for elaborating on its fix.

Meanwhile, until the bug in that generator is not fixed, you'd have to set min and max manually, as a workaround for the particular case.