getting error message from server during API call

瘦欲@ 提交于 2020-01-05 04:15:11

问题


I have an app where I used RxSwift for my networking by extending ObservableType this works well but the issue I am having now is when I make an API request and there is an error, I am unable to show the particular error message sent from the server. Now how can I get the particular error response sent from the server

extension ObservableType {

    func convert<T: EVObject>(to observableType: T.Type) -> Observable<T> where E: DataRequest {

        return self.flatMap({(request) -> Observable<T> in

            let disposable = Disposables.create {
                request.cancel()
            }

            return Observable<T>.create({observer -> Disposable in

                request.validate().responseObject { (response: DataResponse<T>) in
                                        switch response.result {
                    case .success(let value):

                        if !disposable.isDisposed {
                            observer.onNext(value)
                            observer.onCompleted()
                        }
                    case .failure(let error):

                        if !disposable.isDisposed {
                            observer.onError(NetworkingError(httpResponse: response.response,
                                                             networkData: response.data, baseError: error))
                            observer.onCompleted()
                        }

                    }
                }

                return disposable
            })

        })
    }

}

let networkRetryPredicate: RetryPredicate = { error in
    if let err = error as? NetworkingError, let response = err.httpResponse {
        let code = response.statusCode
        if code >= 400 && code < 600 {
            return false
        }
    }

    return true
}

// Use this struct to pass the response and data along with 
// the error as alamofire does not do this automatically
public struct NetworkingError: Error {
    let httpResponse: HTTPURLResponse?
    let networkData: Data?
    let baseError: Error
}

response from the server could be

{
  "status" : "error",
  "message" : " INSUFFICIENT_FUNDS"
}

or

{
  "status" : "success",
  "data" : " gghfgdgchf"
}

my response is handled like this

class MaxResponse<T: NSObject>: MaxResponseBase, EVGenericsKVC {
    var data: T?

    public func setGenericValue(_ value: AnyObject!, forUndefinedKey key: String) {
        switch key {
        case "data":
            data = value as? T
        default:
            print("---> setGenericValue '\(value)' forUndefinedKey '\(key)' should be handled.")
        }
    }

    public func getGenericType() -> NSObject {
        return T()
    }
}

the error is

return ApiClient.session.rx.request(urlRequest: MaxApiRouter.topupWall(userId: getUser()!.id!, data: body))
            .convert(to: MaxResponse<Wall>.self)

回答1:


In the official Alamofire docs it is mentioned that validate(), without any parameters:

Automatically validates status code within 200..<300 range, and that the Content-Type header of the response matches the Accept header of the request, if one is provided.

So if you do not include Alamofire's validate() you are saying that no matter the status code, if the request did get through, you will consider it successful, so that's why it shows nothing in the failure block.

However if you prefer to use it, yes, it will give you an ResponseValidationFailureReason error, but you still have access to the response.data. Try printing it, you should see the expected error response from the server:

if let responseData = response.data {
    print(String(data: responseData, encoding: .utf8))
}


来源:https://stackoverflow.com/questions/55865017/getting-error-message-from-server-during-api-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!