You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Alamofire处理错误响应时重复读取响应体引发JSON序列化失败问题排查

解决Alamofire RequestInterceptor导致的重复响应体解码失败问题

你的问题核心是拦截器错误地对非401状态码的请求触发了重试逻辑,导致Alamofire重复读取响应数据流,把两次相同的JSON内容拼接在一起,最终触发了"Garbage at end"的JSON解码错误。

问题分析

从错误日志里能明显看到响应体被重复输出了两次:{"message": "User with same email already exists"} {"message": "User with same email already exists"},这显然不是服务器返回的原始内容——因为请求被不必要地重试后,响应数据流只能被读取一次,第二次读取时会出现数据拼接异常,最终变成无效的JSON格式。

你的拦截器应该是在遇到所有错误响应时都执行了重试,而非仅针对401未授权场景,这就导致像400这类业务错误也被重复处理,引发了解码失败。

解决方案

1. 限制拦截器仅对401状态码触发重试

修改你的RequestInterceptor实现,确保只有当响应状态码为401时,才执行刷新token和重试逻辑,其他错误直接跳过:

class AuthInterceptor: RequestInterceptor {
    func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
        // 先判断是否为HTTP响应错误
        guard let httpResponse = request.task?.response as? HTTPURLResponse else {
            completion(.doNotRetry)
            return
        }
        
        // 仅在401未授权时处理重试逻辑
        if httpResponse.statusCode == 401 {
            // 执行你的JWT刷新逻辑
            self.refreshJWTToken { success in
                if success {
                    // 刷新成功,重试请求
                    completion(.retry)
                } else {
                    // 刷新失败,终止重试并返回错误
                    completion(.doNotRetryWithError(error))
                }
            }
        } else {
            // 非401错误,直接终止重试
            completion(.doNotRetry)
        }
    }
    
    // 你的token刷新方法示例
    private func refreshJWTToken(completion: @escaping (Bool) -> Void) {
        // 这里实现你的token刷新逻辑,比如调用后端刷新接口
        // ...
    }
}

2. 调整请求的validate规则(可选)

你当前的validate(statusCode: [200, 401])会把401以外的状态码标记为错误,这本身没问题,但要确保拦截器不对这些错误触发重试。如果业务需要处理其他状态码的响应,可以考虑移除validate,或者在响应回调中手动判断状态码进行处理。

3. 检查拦截器的adapt方法

确保你的拦截器在adapt方法中没有做额外的重复请求处理,adapt仅用于请求发送前的参数/头信息适配,重试逻辑应该只放在retry方法中。

为什么.responseString只看到一次内容?

这是因为responseString的处理逻辑和responseDecodable不同,当重试触发时,第二次的响应数据可能没有被完整捕获,或者responseString在处理时自动忽略了异常的数据流,但本质问题还是不必要的重试导致的。

总结

通过限制拦截器仅对401状态码执行重试,就能避免非授权错误被重复处理,从根源上解决响应体重复拼接导致的JSON解码失败问题。

内容的提问来源于stack exchange,提问作者Peter Hlavatík

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 12:52:30