将 Moya 响应错误转换为定义的类型

Casting Moya Response error to defined type

我正在使用 RxMoya 进行网络调用并扩展 PremitiveSequence 和 Response 以处理返回的错误。我声明了一个网络错误结构,我可以使用它来获取所有错误详细信息,因此通过 BaseResponse 模型传递错误消息。这是我的 NetwokingError 结构

public struct NetworkingError: Error {
    let httpResponse: HTTPURLResponse?
    let networkData: Data?
    let baseError: Error
}

为了我的编码,我扩展了原始序列如下

public 扩展 PrimitiveSequence 其中 TraitType == SingleTrait,

ElementType == Response {

    func mapObject<T: Codable>(_ type: T.Type, path: String? = nil) -> Single<T> {
        return flatMap { response -> Single<T> in
            return Single.just(try response.mapObject(type, path: path))
        }
    }

    func mapArray<T: Codable>(_ type: T.Type, path: String? = nil) -> Single<[T]> {
        return flatMap { response -> Single<[T]> in
            return Single.just(try response.mapArray(type, path: path))
        }
    }

    func filterSuccess() -> Single<E> {
        return flatMap { (response) -> Single<E> in
            if 200 ... 299 ~= response.statusCode {
                return Single.just(response)
            }

            print("THIS ERROR JSON jsonObject2 xx mm \(response.data)")

            do {
                let jsonObject2 = try JSONSerialization.jsonObject(with: response.getJsonData(), options: .allowFragments)
                print("THIS ERROR JSON jsonObject2 xx \(jsonObject2)")
                let jsonObject = try JSONSerialization.jsonObject(with: response.getJsonData(), options: .allowFragments) as? NetworkingError

                print("THIS ERROR JSON  xx \(jsonObject)")
                return Single.error(jsonObject ?? NetworkingError.self as! Error)
            }
        }
    }
}

如果我在此处 运行 此代码,应用程序会崩溃 return Single.error(jsonObject ?? NetworkingError.self as! Error)

在我的代码中,我正在传递像

这样的数据
func postVerifyApp(challenge: Int, identifier: String) -> Observable<AuthResponse> {

        return provider.rx.request(.postVerifyApp(challenge: challenge, identifier: identifier))

            .filterSuccess()
            .mapObject(AuthResponse.self)
            .asObservable()
            .flatMap({ authResponse -> Observable<AuthResponse> in
                return self.sendTokenToServer(authResponse)
            })
    }

然后我在演示者中使用它 class 就像这样

func postVerifyApp(challenge: Int, identifier: String) {
        view?.setProgress(enabled: true)
        source.postVerifyApp(challenge: challenge, identifier: identifier)
            .retry(.delayed(maxCount: 2, time: 2.5), shouldRetry: networkRetryPredicate)
            .asSingle()
            .subscribe(onSuccess: { [weak self] response in
                guard let presenter = self, let view = presenter.view else {return}
                view.setProgress(enabled: false)
                log(response, .json)
                guard let data = response.data else {
                    return }

                view.showVerifySuccess()
                }, onError: { [weak self] error in
                    guard let presenter = self, let view = presenter.view else {return}
                    print("MESSAGE X \(error.localizedDescription)")
                    if let error = error as? NetworkingError {
                        print("MESSAGE X httpResponse \(error.httpResponse)")
                    }
                    view.setProgress(enabled: false)

            }).disposed(by: disposeBag)
    }

我希望能够传递此错误并提取错误消息并将其传递到控制台。

这是我的基本模型的样子

struct ResponseBase<T: Codable>: Codable {
    var error: Bool?
    var message: String?
    var data: T

    var isSucessful: Bool {
        return error == false
    }

}

用于构造 Single.error 的表达式无法转换为错误。首先,您试图将 jsonObject(字典)转换为错误。在右侧,在 ifNull 表达式上,您试图将元类型 (Networking.Type) 转换为错误。

要解决您的投射问题,您可以使用这个经过修改的 NetworkingError。

public struct NetworkingError: Error {

    let httpResponse: HTTPURLResponse?
    let networkData: Data?
    let baseError: MoyaError

    init(_ response:Response) {
        self.baseError = MoyaError.statusCode(response)
        self.httpResponse = response.response
        self.networkData = response.data
    }

    func getLocalizedDescription() -> String {

       return self.baseError.localizedDescription
    }
}

有了这个,修改 filterSuccess 中的闭包以创建 NetworkingError 对象,将 Response 传递给它,就像这样:

func filterSuccess() -> Single<E> {
    return flatMap {
        (response) -> Single<E> in
        if 200 ... 299 ~= response.statusCode {
           return Single.just(response)
        } else {
           let netError = NetworkingError(response)
           return Single.error(netError)
        }
    }
}

我鼓励你看一下 MoyaError 定义