Swift使用Alamofire RequestInterceptor如何返回服务端原始错误?
问题原因与解决方案
根因分析
问题出在你请求末尾调用的.validate()方法:
- Alamofire默认的
.validate()仅将200~299区间的状态码判定为成功,其余状态码会直接抛出unacceptableStatusCode错误,进入拦截器的retry流程 - 当错误非401时,你调用
completion(.doNotRetryWithError(error))会将Alamofire包装的错误直接返回,不会走到你原本在success回调里自定义的状态码判断、错误解析逻辑,所以你只能拿到包装后的requestRetryFailed错误,拿不到服务端返回的原始错误数据。
修复方案
方案1:移除默认validate校验(推荐)
你已经在responseData回调中自定义了状态码判断逻辑,完全不需要Alamofire的默认校验,直接移除请求末尾的.validate()即可:
func requestWithAlamofire(with baseURL: URL) -> DataRequest { var params:[String: Any]! params = self.params?.dictionary ?? [:] debugPrint("request params: ", params) let urlString = baseURL.appendingPathComponent(path).absoluteString.removingPercentEncoding ?? "" debugPrint(urlString) let url = URL(string: urlString) ?? baseURL.appendingPathComponent(path) if self.method == .post || self.method == .put || self.method == .delete { // 移除末尾的.validate() return AF.request(url, method: self.method, parameters: params, encoding: JSONEncoding.default, headers: httpHeader, interceptor: self) } // 移除末尾的.validate() return AF.request(url, method: self.method, parameters: params, headers: httpHeader, interceptor: self) }
修改后所有请求无论状态码是多少都会进入success回调,你原本写的非200状态码错误解析逻辑会正常生效,401状态码也可以正常被拦截器捕获触发重试逻辑,不受影响。
方案2:保留默认校验,从错误中提取原始响应
如果你需要保留Alamofire的默认校验逻辑,可以在failure回调中从AFError里提取原始响应数据自行解析:
case .failure(let error): debugPrint(error) // 从AFError中取出原始响应数据和状态码 if let afError = error as? AFError, let statusCode = afError.responseCode, let errorData = afError.responseData { let err = NSError(domain: "", code: statusCode, userInfo: JSON(errorData).dictionaryObject) observer.onError(err) } else { observer.onError(error) }
内容的提问来源于stack exchange,提问作者Tomer
相关产品推荐
相关产品推荐

