在远程服务返回401时,我试图根据响应状态代码添加一个检查。
我正在尝试使用PromiseKit URLSession扩展。
想象一下我有一些基本的东西,比如
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.compactMap {
try JSONDecoder().decode(T.self, from: $0.data)
}我想要做的是根据响应状态代码添加一个检查,这样我就可以抛出一个错误并执行一些进一步的步骤。
有点像
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.map { session in
if (session.response as? HTTPURLResponse)?.statusCode == 401 {
// throw a custom error here
// something like
// throw TokenProviderError.unauthorized
}
return session.data
}.compactMap {
try JSONDecoder().decode(T.self, from: $0)
}.catch { error in
// check the error thrown here and do something
}这有一个例外
无法将“PMKFinalizer”类型的返回表达式转换为返回类型“承诺”
是否有可能引入像retryWhen这样的东西来捕获错误并进行检查?
发布于 2019-10-08 11:26:07
因为.catch不返回任何东西,但是您想返回一个Promise<T>,所以您必须在这里删除.catch,
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.map { session in
if (session.response as? HTTPURLResponse)?.statusCode == 401 {
// throw a custom error here
// something like
// throw TokenProviderError.unauthorized
}
return session.data
}.compactMap {
try JSONDecoder().decode(T.self, from: $0)
}.catch将由被调用方实现。
或者,也许你看起来像,
func test() -> Promise<Any> {
return firstly(execute: { () -> Promise<String> in
return .value("bhai")
}).map({ string -> Promise<Double?> in
return .value(0.1)
}).compactMap({ double -> NSError in
return NSError(domain: "", code: 0, userInfo: nil)
})
}发布于 2020-03-31 18:29:07
我试图实现和您完全一样的功能,我认为您正在寻找的retrywhen特性是recover,您可以在GitHub PromiseKit文档中找到它。
return firstly {
URLSession.shared.dataTask(.promise, with: request)
}.map { session in
if (session.response as? HTTPURLResponse)?.statusCode == 401 {
throw TokenProviderError.unauthorized
}
return session.data
}.compactMap {
try JSONDecoder().decode(T.self, from: $0)
}
// above is a copy of your code
.recover { error in // instead of .catch, use .recover here
guard let err = error as? TokenProviderError,
err == .unauthorized
else { throw error } // we only care 401 error here, other error will be handled in caller's .catch
// in my case, the reason for 401 error is due to an expired access token, so I will try to use refresh token to get a valid access token and make the same request again
return firstly {
loginWithRefreshToken(token: myRefreshToken)
}.then { loginRes -> Promise<(data: Data, response: URLResponse)> in
// loginRes contains new access token, set it to request "Authorization" header, and make the same request again
request.setValue(loginRes.accessToken, forHTTPHeaderField: "Authorization")
return URLSession.shared.dataTask(.promise, with: request)
}.map { session -> Data in
return session.data
}.compactMap { data -> Promise<T> in
try JSONDecoder().decode(T.self, from: data)
}
}也许现在回答起来有点晚了,但我希望它能帮助一些像我这样新加入PromiseKit的程序员。
https://stackoverflow.com/questions/58285240
复制相似问题