Search code examples
iosswiftalamofirerx-swift

how to determine the specific 409 error from an AFError?


I have a method that returns a Single<(HTTPURLResponse, Any)> doing a call to a webservice.

This call returns an 409 for multiple reasons and this reason is passed as a JSON in the response. I know the JSON is in the data attribute of the DataResponse object but I would like to have it in the AFError that I pass when an error occurs. I want to display the specific 409 error message related to the JSON response to the user to allow him understand what happened.

How could I do that ?

I searched for that in Stackoverflow and also on the github of Alamofire but couldn't find any help to my case.

return Single<(HTTPURLResponse, Any)>.create(subscribe: { single in
    let request = self.sessionManager.request(completeURL, method: httpMethod, parameters: params, encoding: encoding, headers: headers)
    request.validate().responseJSON(completionHandler: { (response) in
        let result = response.result
        switch result {

        case let .success(value): single(.success((response.response!, value)))
        case let .failure(error): single(.error(error))
        }
    })

    return Disposables.create { request.cancel() }
})

I'm working with Alamofire 4.9.1


Solution

  •  request.validate().responseJSON { (response) in
    
    
            let statusCode = response.response?.statusCode ?? 0
    
            guard statusCode !=  409 else {
    
                if let data = response.data, let errorJson = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                    let errorMessage = errorJson["message"] as? String
                    let customError = CustomError(message: errorMessage)
                    single(.error(customError))
                }
    
    
                return
            }
    
    
            let result = response.result
    
            switch result {
            case let .success(value): single(.success((response.response!, value)))
            case let .failure(error): single(.error(error))
            }
        }
    

    I guess you can achieve your requirement by this way. create a custom Error class to pass the error to completion. dont forget to call completion if errorJson is not serialised.

    class CustomError: Error {
    
    var localizedDescription: String { message ?? "" }
    
    var message: String?
    
    init(message: String?) {
        self.message = message
    }
    

    }