получение сообщения об ошибке от сервера во время вызова API - PullRequest
1 голос
/ 26 апреля 2019

У меня есть приложение, в котором я использовал RxSwift для своей сети, расширяя ObservableType, это работает хорошо, но проблема, с которой я сейчас сталкиваюсь, заключается в том, что когда я делаю запрос API и возникает ошибка, я не могу показать конкретное сообщение об ошибке, отправленноес сервера.Теперь, как я могу получить конкретный ответ об ошибке, отправленный с сервера

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
}

ответ от сервера может быть

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

или

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

мой ответобрабатывается так

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()
    }
}

ошибка

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

1 Ответ

0 голосов
/ 15 мая 2019

В официальных документах Alamofire упоминается, что validate(), без каких-либо параметров :

Автоматически проверяет код состояния в пределах 200 .. <300, и что заголовок Content-Type ответа соответствует заголовку Accept запроса, если он указан. </p>

Так что, если вы не включите validate() Alamofire, вы говорите, что нетНезависимо от кода состояния, если запрос все же прошел, вы посчитаете его успешным, поэтому в блоке сбоев он ничего не показывает.

Однако, если вы предпочитаете его использовать, да, он даст вамResponseValidationFailureReason ошибка, но у вас все еще есть доступ к response.data.Попробуйте распечатать его, вы должны увидеть ожидаемое сообщение об ошибке от сервера:

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