在我的远程服务返回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
的内容,使我能够发现错误并进行检查?
答案 0 :(得分:1)
我试图实现与您完全相同的目标,我认为您正在寻找的retrywhen
功能称为recover
,您可以在GitHub PromiseKit Document中找到它>
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陌生的一些编码人员。
答案 1 :(得分:0)
由于.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)
})
}