如何从MoyaError获取错误响应

时间:2017-06-30 16:24:57

标签: swift3 rx-swift moya

类似于this,但这次我需要检索服务器的JSOn响应。

这是我现有的代码:

    <footer class="footer">
    <div class="container">
      <div class="row">
          <div style="float:none;margin:0 auto;" id="toplist" class="col-md-12 col-xs-3 text-center">
             <ul >
                <a style="color:white;" href="https://example.com/"><li id="first" style="list-style:none;display: inline;">HOME</li></a>
                <a style="color:white;" href="https://example.com/service"><li style="list-style:none;display: inline;padding-left:30px;">SERVICE</li></a>
                <a style="color:white;" href="https://example.com/examples"><li style="list-style:none;display: inline;padding-left:30px;">EXAMPLES</li></a>
                <a style="color:white;" href="https://example.com/order"><li style="list-style:none;display: inline;padding-left:30px;">ORDER</li></a>
                <a style="color:white;" href="https://example.com/contact"><li style="list-style:none;display: inline;padding-left:30px;">CONTACT</li></a>
             </ul>
          </div>
          <div id="hello" class="col-md-12 col-xs-9 text-center">
      © 2017 site.com
          </div>
      </div>
      </div>
    </div>
    </footer>

我的问题是:我可以通过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但我也希望获得404 HTTP请求的JSON响应。

2 个答案:

答案 0 :(得分:0)

由于您的服务器响应也包含在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. 如果错误无效,则抛出错误,表示可观察操作失败。
  4. 响应验证

    要将响应验证代码保存在正确的位置,您可以在响应类定义中定义一个类函数,以验证它是否有效:

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

答案 1 :(得分:0)

我遇到了同样的问题,对我来说,最简单,最干净的解决方案是扩展MoyaError以包含已解码错误对象的属性。在我的情况下,我正在使用Decodable个对象,因此您可以为可解码的BackendError编写类似这样的内容,以表示您可能从服务器获得的错误:

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

如果您更喜欢直接处理JSON,则可以调用mapJSON方法,而不是映射到Decodable

然后,您只需执行以下操作即可获取非成功状态代码的错误信息:

onError: { error in
    let backendError = (error as? MoyaError).backendError
}