disneystreaming / smithy-translate

Other
53 stars 12 forks source link

Reusing 204 / NoContent response #240

Closed ctjhoa closed 4 months ago

ctjhoa commented 5 months ago

Hi,

First, thanks for this lib. I found an unhandled case using the following OpenAPI:

# dummy-openapi.yaml
openapi: 3.0.0
info:
  title: Sample API
  description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
  version: 0.1.9
servers:
  - url: http://api.example.com/v1
    description: Optional server description, e.g. Main (production) server
  - url: http://staging-api.example.com
    description: Optional server description, e.g. Internal staging server for testing
paths:
  /users:
    get:
      summary: Returns a list of users.
      description: Optional extended description in CommonMark or HTML.
      responses:
        '204':
          $ref: '#/components/responses/NoContent'   # <-----
# Descriptions of common components
components:
  responses:
    NoContent:
      description: The specified resource was not found

It gives the following exception

% smithytranslate openapi-to-smithy --input dummy-openapi.yaml --force output
Failed to validate the Smithy model:
[ERROR] dummy_openapi#UsersGET: operation shape has an `output` relationship to an unresolved shape `dummy_openapi#ComponentsResponsesNoContent` | Target.UnresolvedShape N/A:0:0
Exception in thread "main" software.amazon.smithy.model.node.ExpectationNotMetException: Shape not found in model: dummy_openapi#ComponentsResponsesNoContent
        at software.amazon.smithy.model.Model.lambda$expectShape$1(Model.java:713)
        at java.base/java.util.Optional.orElseThrow(Optional.java:408)
        at software.amazon.smithy.model.Model.expectShape(Model.java:713)
        at software.amazon.smithy.model.shapes.SmithyIdlModelSerializer.getInlineableShapes(SmithyIdlModelSerializer.java:197)
        at software.amazon.smithy.model.shapes.SmithyIdlModelSerializer.serialize(SmithyIdlModelSerializer.java:169)
        at software.amazon.smithy.model.shapes.SmithyIdlModelSerializer.lambda$serialize$1(SmithyIdlModelSerializer.java:145)
        at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:178)
        at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
        at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1764)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
        at software.amazon.smithy.model.shapes.SmithyIdlModelSerializer.serialize(SmithyIdlModelSerializer.java:145)
        at smithytranslate.cli.runners.openapi.ReportResult.getSmithyFiles(ReportResult.scala:57)
        at smithytranslate.cli.runners.openapi.ReportResult.apply(ReportResult.scala:99)
        at smithytranslate.cli.runners.OpenApi$.$anonfun$runOpenApi$1(OpenApi.scala:27)
        at smithytranslate.cli.runners.OpenApi$.$anonfun$runOpenApi$1$adapted(OpenApi.scala:27)
        at smithytranslate.cli.runners.OpenApi$.runOpenApi(OpenApi.scala:39)
        at smithytranslate.cli.Main$$anonfun$$lessinit$greater$1.apply(Main.scala:51)
        at smithytranslate.cli.Main$$anonfun$$lessinit$greater$1.apply(Main.scala:48)
        at scala.Function1.$anonfun$andThen$1(Function1.scala:87)
        at scala.Function1.$anonfun$andThen$1(Function1.scala:87)
        at cats.data.Validated.andThen(Validated.scala:727)
        at com.monovore.decline.Parser$Accumulator$Validate.$anonfun$mapValidated$1(Parser.scala:413)
        at scala.Function1.$anonfun$andThen$1(Function1.scala:87)
        at cats.data.Validated.andThen(Validated.scala:727)
        at com.monovore.decline.Result.$anonfun$mapValidated$2(Result.scala:13)
        at cats.instances.Function0Instances$$anon$4.$anonfun$map$1(function.scala:100)
        at com.monovore.decline.Parser.evalResult(Parser.scala:30)
        at com.monovore.decline.Parser.$anonfun$consumeAll$3(Parser.scala:107)
        at scala.util.Either.flatMap(Either.scala:352)
        at com.monovore.decline.Parser.$anonfun$consumeAll$1(Parser.scala:107)
        at scala.Option.map(Option.scala:242)
        at com.monovore.decline.Parser.consumeAll(Parser.scala:106)
        at com.monovore.decline.Parser.apply(Parser.scala:19)
        at com.monovore.decline.Command.parse(opts.scala:20)
        at smithytranslate.cli.CommandApp.main(CommandApp.scala:81)
        at smithytranslate.cli.Main.main(Main.scala)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at coursier.bootstrap.launcher.a.a(Unknown Source)
        at coursier.bootstrap.launcher.Launcher.main(Unknown Source)

whereas this is a valid OpenAPI schema.

2024-04-08-155123_1920x1020_scrot

204 / NoContent doesn't seems to be handled properly when reusing responses.

Here is the related OpenAPI documentation:

lewisjkl commented 5 months ago

Hey @ctjhoa thank you for reporting this, I will take a look and see what I can figure out.