OpenAPITools / OpenAPITools/openapi-generator

[BUG] [SWIFT] Cannot read custom error codes using Swift auto-generated code.

Open
#5,504 7 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Description

Hello,

My backend uses this for errors:
https://jsonapi.org/format/#errors

So, errors look like this:

  {
  "meta" : [

  ],
  "errors" : [
    {
      "status" : 409,
      "detail" : "A user with that email address already exists",
      "code" : "13001"
    }
  ]
}

The open api specification file I have, uses that. For example, this is a request:

/directory/customers:
  post:
    tags:
    - Directory
    summary: Create a new customer
    description: "This endpoint creates a new customer. XXXX users are reffered\
      \ to as customers in the api.\nAll users have a customer record. A customer\
      \ has a client account and a pro account. All customers\nhave a client account\
      \ but only a subsection have a pro account.\n\nTo sign up a client, post to\
      \ this endpoint and add client information: The request will look something\
      \ like this:\n\n```json\n{\n\t\"data\" : {\n\t\t\"type\": \"CUSTOMERS\",\n\
      \t\t\"attributes\" : {\n\t\t\t\"password\" : \"tester\",\n\t\t\t\"client\"\
      : {\n\t\t\t\t\"username\": \"jane.doe\",\n\t\t\t\t\"email\": \"jane.doe@foobar.com\"\
      \n\t\t\t}\n\t\t}\n\t}\n}\n```\n\nYou will then receive a new client with and\
      \ access token. The metadata of the client will contain onboarding information\n\
      (These are the items of data they have provided). You can use this information\
      \ to make PATCH requests to add any extra\ninformation that is needed\n\n\
      Security wise you need:\n\n- The api key of your application passed through\
      \ the `x-api-key` header\n"
    operationId: directoryCustomersIdPost
    requestBody:
      description: Request for creating a customer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CustomerPostRequest'
    responses:
      "201":
        description: Customer was created
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Customer'
      "409":
        description: Duplicate customer
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ErrorResponseBS'
      default:
        description: Error
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ErrorResponseBS'
    security:
    - ApiVersion: []
      ApiKey: []

As you can see, it has a custom error structure.
And here you have the error structure:

ErrorResponseBS:
     required:
     - errors
     type: object
     properties:
       errors:
         type: array
         items:
           $ref: '#/components/schemas/ErrorItem'
     description: |
       When an error is encounterred. This will be returned. This will contain a list of errors. Each error contains
       a status (http status) ans detail. The detail is human readable
   ErrorItem:
     required:
     - code
     - detail
     - status
     type: object
     properties:
       status:
         type: string
       code:
         type: string
       detail:
         type: string

The reason we use ErrorResponseBS instead of ErrorResponse is because the code generator said that keyword was already used by the system.

The thing is, if I receive an error from the backend (json at the top), Swift only shows this in the debugger when I check what is inside the error variable:

▿ Optional<Error>
 ▿ some : ErrorResponse
   ▿ error : 3 elements
     - .0 : 409
     ▿ .1 : Optional<Data>
       ▿ some : 109 bytes
         - count : 109
         ▿ pointer : 0x00006000020f2370
           - pointerValue : 105553150813040
     ▿ .2 : AFError
       ▿ responseValidationFailed : 1 element
         ▿ reason : ResponseValidationFailureReason
           ▿ unacceptableStatusCode : 1 element
             - code : 409

As you can see, there is nothing "code" : "13001".
And that is a serious problem, because we have several error codes and the app does different things depending on the error code, for example the UI is different depending on if the error is email already taken or username already taken.

What can I do? Am I missing something? Any workaround? How do you send error codes right now?

Thanks a lot for suggestions.

Can you check this @4brunu ? I am sure you know something :)
I see you wrote:
https://github.com/OpenAPITools/openapi-generator/pull/5068
Thanks.

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
    Yes. I attach yaml sections and logs.

  • Have you validated the input using an OpenAPI validator (example)?
    I tried but the website does not work. Anyway, the generated code appears to work perfectly, the error thing is the only issue I have.

  • What's the version of OpenAPI Generator used?
    4.2.3

  • Have you search for related issues/PRs?
    Yes. There is one related:
    https://github.com/OpenAPITools/openapi-generator/pull/5068
    But this one is only about using a generic ErrorResponse, instead of the error described by the open api specification file.

  • What's the actual output vs expected output?
    The error should be ErrorResponseBS type (with an error code inside), instead of ErrorResponse.

  • [Optional] Bounty to sponsor the fix (example)
    Thinking about that.

openapi-generator version

4.2.3

OpenAPI declaration file content or url

Sections up here.

Command line used for generation

openapi-generator generate -g swift5 -i openapi.yaml -o ./generated --library alamofire

Steps to reproduce

Just use a specification file with a custom error structure. Then, trigger and error and use a breakpoint to inspect the content.

Related issues/PRs

https://github.com/OpenAPITools/openapi-generator/pull/5068

Suggest a fix

I think the code generator should respect the type selected in the specification file.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the swift5 generator entry point and reproduce the issue using the documented openapi-generator command with the supplied ErrorResponseBS and ErrorItem schemas. Compare the generated handling of a 409 response with the expected ErrorResponseBS structure, including code 13001; done means the custom error type and code are available to the Swift client.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, openapi, swift
Domain
api, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.