Skip to content

Generated code for error clauses is stringly-typed #5284

@jducoeur

Description

@jducoeur

Context: https://softwaremill.community/t/how-best-to-go-about-proposing-and-helping-with-code-generation-improvements/542

Tapir version: 1.13.19

Given an OpenAPI spec including something like this:

responses:
  '200':
    description: Success
    content:
      text/plain:
        schema:
          type: string
          example: Success
  '400':
    description: Bad parameters
    content:
      text/plain:
        schema:
          type: string
          example: Example bad parameter message
  '404':
    description: Missing a bit
    content:
      text/plain:
        schema:
          type: string
          example: The missing details message
  '500':
    description: Failure
    content:
      text/plain:
        schema:
          type: string
          example: Failure

The generated errorOut clause looks like:

.errorOut(oneOf[String](
  oneOfVariant[String](sttp.model.StatusCode(400), stringBody.description("Bad parameters")),
  oneOfVariant[String](sttp.model.StatusCode(404), stringBody.description("Missing a bit")),
  oneOfVariant[String](sttp.model.StatusCode(500), stringBody.description("Failure"))))

The problem is, oneOfVariant is class-based according to the docs. Since all three of these are strings, anything returned will match the first one and produce a 400. You have to do some rather ugly and fragile hackery in the server logic to produce the desired return code.

Worse yet, if there is no description on one of those response codes, it assigns an empty string body as the marker, making it more or less impossible (AFAICT) for the serverLogic to produce the desired code!

All of this is pretty unfortunate from a logic POV. I want to be able to have my server logic produce the status code in the returned value, and have the string body not matter to the variant matching. The current approach forces the code to be stringly-typed, which makes my Scala-centric heart sad.

I'm happy to help work to make this enhancement happen, but we definitely need to talk about what the ideal outcome would look like, and how to get there without breaking existing Tapir users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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