解决java.lang.IllegalStateException:拦截器需关闭响应的问题
解决OkHttp拦截器重试时的IllegalStateException问题
报错原因
你遇到的java.lang.IllegalStateException: cannot make a new request because the previous response is still open: please call response.close()错误,核心原因是重试逻辑中未关闭上一次的响应资源。OkHttp的连接机制要求,同一连接上的新请求必须等前一个响应完全关闭后才能发起,否则会触发该异常。
修复方案
在每次发起重试请求前,安全关闭上一次的响应对象。推荐使用OkHttp提供的closeQuietly()方法,它能避免因响应已关闭而抛出额外异常。
修改后的完整代码
class AppInterceptor: Interceptor { override fun intercept(chain: Interceptor.Chain): Response { var request = chain.request() try { var response = chain.proceed(request) var tryCount = 0 val maxTries = 5 while (!response.isSuccessful && tryCount < maxTries) { tryCount++ // 安全关闭上一次的响应,释放连接资源 response.closeQuietly() Thread.sleep(1500) request = request.newBuilder().build() response = chain.proceed(request) } return response } catch (e: Exception) { e.printStackTrace() val message: String = when (e) { is SocketTimeoutException -> Constants.SOCKET_TIMEOUT is UnknownHostException -> Constants.UNKNOWN_HOST is ConnectionShutdownException -> Constants.CONNECTION_SHUTDOWN is IOException -> Constants.IO_EXCEPTION_MESSAGE is IllegalStateException -> "${e.message}" else -> "${e.message}" } return Response.Builder() .request(request) .protocol(Protocol.HTTP_1_1) .code(999) .message(message) .body("{${e}}".toResponseBody(null)) .build() } } }
关键说明
closeQuietly()的作用:这是OkHttp为Response类提供的扩展方法,会静默关闭响应流和连接,即使响应已处于关闭状态也不会抛出异常,比直接调用response.close()更安全。- 不要关闭最终返回的响应:最后return的response需要传递给后续的拦截器或业务代码处理(比如Retrofit会自动负责关闭响应资源),如果提前关闭会导致后续无法读取响应内容。
- 额外修正:原代码中
body("{${e}".toResponseBody(null))存在语法错误,少了闭合的},已在修改后的代码中修正。
内容的提问来源于stack exchange,提问作者robson idongesit samuel
相关产品推荐
相关产品推荐

