hey-api / openapi-ts

✨ Turn your OpenAPI specification into a beautiful TypeScript client
https://heyapi.vercel.app
MIT License
634 stars 44 forks source link

@hey-api/client-fetch: Error is unknown when using default #691

Open mlankamp opened 1 week ago

mlankamp commented 1 week ago

Description

The I use a non-200 response code, the Error object is created with a specific type. But if I use response code default the response is created as unknown

OpenAPI specification (optional)

openapi: 3.0.1
info:
  title: Testing
  version: v1
paths:
  '/specific/{id}':
    post:
      tags:
        - Testing
      operationId: SpecficError
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        '500':
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
  '/default/{id}':
    post:
      tags:
        - Testing
      operationId: DefaultError
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: No Content
        default:
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'

components:
  schemas:
    ProblemDetails:
      type: object
      properties:
        type:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        status:
          type: integer
          format: int32
          nullable: true
        detail:
          type: string
          nullable: true
        instance:
          type: string
          nullable: true
      additionalProperties: { }

Configuration

import { defineConfig } from '@hey-api/openapi-ts';

export default defineConfig({
  input: 'source/swagger.yaml',
  output: {
    path: 'output',
    format: false,
    lint: false
  } ,
  client: '@hey-api/client-fetch',
  schemas: false,
  types: {
    enums: 'javascript'
  },
  services: {
    asClass: true,
  }
});

System information (optional)

Example repo: https://github.com/mlankamp/openapi

mlankamp commented 1 week ago

I think the problem is caused by https://github.com/hey-api/openapi-ts/blob/032bd93a7de9696473887aef5d770e2f78fea076/packages/openapi-ts/src/utils/write/types.ts#L403

The causes the error to be filtered twice, because the operation.errors is already assigned with operation.errors = getErrorResponses(operationResponses);

Changing line 403 to : const errorResults = operation.errors; fixes the problem.

mrlubos commented 1 week ago

cc @gergan

gergan commented 1 week ago

Yes I think @mlankamp is correct -> operation.errors are set in operation.ts and they are already filtered through getErrorResponses so no need to filter them once more. It seems that removing the function call is the correct thing to do. Albeit my question is if the logic for the default in https://github.com/hey-api/openapi-ts/blob/a9dfda0afcc125125e8617d6be77f8d8a85e638b/packages/openapi-ts/src/openApi/common/parser/operation.ts#L139 is correct. If I understand the specification correctly https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#fixed-fields-9 or https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#fixed-fields-14 it seems that default covers all the responses, which are not declared. But inferDefaultResponse tries to identify if there are declared success responses and in this way decides if the default is only for error responses...