Alamofire stacking responses

212 Views Asked by At

I am using Alamofire to communicating with my API, also I am using RequestInterceptor to catch unauthorized requests or for refreshing the JWT token. When everything is going well, there is no problem at all, but in case of bad response (400,401) Alamofire tries to refresh token and send the request again. There is a strange behavior, since it fails with serialization error:

[Request]: PUT https://my.url.com/unregistered?
    [Headers]:
        Content-Type: application/json
    [Body]:
        {"name":"user16","email":"[email protected]"}
[Response]:
    [Status Code]: 400
    [Headers]:
        Connection: keep-alive
        Content-Length: 51
        Content-Type: application/json
        Date: Sun, 19 Sep 2021 08:13:57 GMT
        Server: nginx
    [Body]:
        {"message": "User with same email already exists"}
        {"message": "User with same email already exists"}
[Network Duration]: 0.21983695030212402s
[Serialization Duration]: 0.0001439583720639348s
[Result]: failure(Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.}))))))

It basically read the same answer two times and tell me that it's not a JSON serializable. I am absolutely sure that server returns only one response like JSON, what is totally strange is fact that Alamofire doing this at any time, once it get back with successfully serialized body and second time it fails on serialization. This is the code I am using:

func authorization<T: Decodable>(
        _ url: String,
        method: HTTPMethod = .get,
        parameters: Parameters? = nil,
        decoder: JSONDecoder = JSONDecoder(),
        headers: HTTPHeaders? = nil,
        interceptor: RequestInterceptor? = nil,
        withInterceptor: Bool = false
    ) -> Future<T, ServerError> {
        return Future({ promise in
            AF.request(
                url,
                method: method,
                parameters: parameters,
                encoding: JSONEncoding.default,
                headers: headers,
                interceptor: withInterceptor ? self : nil
            )
            .validate(statusCode: [200, 401])
            .responseDecodable(completionHandler: { (response: DataResponse<T, AFError>) in
                print(response.debugDescription)
                switch response.result {
                case .success(let value):
                    self.saveCookies(cookies: HTTPCookieStorage.shared.cookies)
                    promise(.success(value))
                case .failure(let error):
                    promise(.failure(self.createError(response: response.response, AFerror: error, AFIerror: nil, data: response.data)))
                }
            })
        })
    } 

Also, I've tried adding multiple status codes to validation, nothing helps at all.

When I've used .responseString to get any thoughts I was able to see the response only once, which is strange too.

0

There are 0 best solutions below