как получить ответ об ошибке от MoyaError

похоже на this, но на этот раз мне нужно получить ответ сервера JSOn.

вот мой существующий код:

return Observable.create{ observer in
            let _ = self.provider
                .request(.getMerchantDetails(qrId: qrId))
                .filterSuccessfulStatusCodes()
                .mapJSON()
                .subscribe(onNext: { response in
                    observer.onNext(RQRMerchant(json: JSON(response)))
                }, onError: { error in
                    observer.onError(error)
                })
            return Disposables.create()

мой вопрос: я могу получить код ответа об ошибке 404 с помощью error.localizedDescription Но я также хочу получить ответ JSON на запрос HTTP 404.


person Led    schedule 30.06.2017    source источник


Ответы (2)


Поскольку ответ вашего сервера также содержится в JSON, это означает, что ваши onNext выбросы могут быть успешными ответами JSON или недействительными ответами JSON.

Проверьте правильность ответа с помощью оператора do

Вы можете проверить правильность ответа, выполнив следующие действия:

return Observable.create{ observer in

        let _ = self.provider
            .request(.getMerchantDetails(qrId: qrId))
            .filterSuccessfulStatusCodes()
            .mapJSON()
            .do(onNext: { response in 
                 let isValidResponse : Bool = false // check if response is valid

                  if !isValidResponse {
                      throw CustomError.reason
                  }
            })
            .subscribe(onNext: { response in
                observer.onNext(RQRMerchant(json: JSON(response)))

            }, onError: { error in
                observer.onError(error)

            })

        return Disposables.create()
  1. Используйте оператор do
  2. Проверьте, действительно ли выброс onNext является действительным излучением
  3. Выдает ошибку, если она недопустима, что означает сбой наблюдаемой операции.

Проверка ответа

Чтобы сохранить код проверки ответа в нужном месте, вы можете определить функцию класса в определении класса ответа, которая проверяет, действительна она или нет:

class ResponseOfTypeA {
    public class func isValid(response: ResponseOfTypeA) throws {
        if errorConditionIsTrue {
            throw CustomError.reason
        }
    }
}

Чтобы вы могли сделать следующее:

    // Your observable sequence
    .mapJSON()
    .do(onNext: ResponseOfTypeA.isValid)
    .subscribe(onNext: { response in 
        // the rest of your code

    })
person dsapalo    schedule 01.07.2017
comment
Привет, спасибо, что нашли время. Я понимаю, что вы хотите мне сказать, но я хочу получить ответ сервера в формате JSON с ответом HTTP 404. - person Led; 03.07.2017

Я столкнулся с той же проблемой, и для меня самым простым и чистым решением было расширить MoyaError, чтобы включить свойство для декодированного объекта ошибки. В моем случае я использую Decodable объекты, поэтому вы можете написать что-то вроде этого для декодируемого BackendError, представляющего ошибку, которую вы можете получить от вашего сервера:

extension MoyaError {
    public var backendError: BackendError? {
        return response.flatMap {
            try? $0.map(BackendError.self)
        }
    }
}

Если вместо этого вы предпочитаете напрямую работать с JSON, вы можете вызвать mapJSONmethod вместо сопоставления с Decodable.

Затем вам просто нужно сделать следующее, чтобы получить информацию об ошибке для неуспешных кодов состояния:

onError: { error in
    let backendError = (error as? MoyaError).backendError
}
person José González    schedule 26.10.2017