swagger-api / swagger-api/swagger-codegen

[Swift] Access server-provided error response in AlamofireDecodableRequestBuilder

Open
#7,132 2 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Client: Swift General: Suggestion
Dominant language
Mustache
Stars
17.8k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

Description

Our API server returns a String error message that gives additional information as to why the request failed. A good example is when the user logs in using our API, the server returns either a userProfile object (successful login) or a user friendly error message as a String such as "Invalid password" which is better than just giving an Alamofire error code. Unfortunately, given the current implementation in AlamofireImplementations.swift, we are unable to access this message when the server's response is not a userProfile object as the swagger client expects for a successful response. However, Alamofire does receive the data object/response from the server—it just doesn't provide us an opportunity to use this response because it ignores the data received and just passes an Alamofire error to the API method.

Swagger-codegen version

swagger-codegen-cli-2.3.0-20171022.172748-209.jar

Suggest a fix/enhancement

The following fixes the solution for our specific implementation, and could help to guide in creating a solution overall, although we should ensure it works for everyone first. Our error responses are formatted as strings for example, but even still this should be backwards compatible if people are already successfully using it will the existing method implementation.

Changing the following code in AlamofireImplementations.swift:

guard dataResponse.result.isSuccess else {
                    completion(nil, ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!))
                    return
                }

to the following code will address the issue:

guard dataResponse.result.isSuccess else {

                    if let errorMessageData = dataResponse.data {
                        if let errorMessage = String(data: errorMessageData, encoding: String.Encoding.utf8) {
                                completion(nil, ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, ErrorResponse.KnownError(errorMessage)))
                        }
                    }
                    else {
                         completion(nil, ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data,dataResponse.result.error!))
                    }
                    return
                }

Additionally it's required to add the following case to the ErrorResponse enum in Models.swift:

public enum ErrorResponse : Error {
    case Error(Int, Data?, Error)
    case KnownError(String)
}

Note: For our specific issue it is resolved only changing it in the default case of T.self within func processRequest, but it's possible this also needs to be implemented in the other cases.

Another potential solution is to find where dataResponse.data is "lost" from the response, and instead include this as part of the error. This is probably a better solution, but could introduce non-backwards compatible changes.

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 in AlamofireImplementations.swift at processRequest, especially the default T.self case, and inspect Models.swift for ErrorResponse. Trace how dataResponse.data is handled for failed responses and compare the other request cases. Done means server-provided error data is accessible without breaking existing error handling across the generated Swift client.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
api
Issue type
Feature
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.