dio icon indicating copy to clipboard operation
dio copied to clipboard

使用 QueuedInterceptorsWrapper 有问题

Open gtyhn opened this issue 3 years ago • 8 comments

使用最新的 4.04 版本

在使用 QueuedInterceptorsWrapper 处理 onError 的 401 状态码,其中刷新 token 成功后使用 dio.fetch 再次请求时,当该请求失败后,则 onError 回调不会触发,造成上层调用方一直处于等待,无法响应,大致代码示例如下:

QueuedInterceptorsWrapper(
    onError: (err, handler) {
      if (err.response?.statusCode == 401) {
        // 刷新 token
        _refreshToken().then((resp) {
          // process token code...

          // token 刷新成功后,继续重发请求,当失败后 onError 不再回调,则上层调用方一直处于等待状态,无法响应
          dio.fetch(err.requestOptions).then(
                (value) => handler.resolve(value),
                onError: (e) => handler.reject(e),
              );
        });
        return;
      }

      handler.next(err);
    },
  );

之前继承 Interceptor 类并使用 lock 的方式没有任何问题,重新请求失败后会再次触发 onError 回调

gtyhn avatar Nov 29 '21 13:11 gtyhn

the same situation

adellko avatar Dec 07 '21 08:12 adellko

the same situation

I confirm this error

codebombi avatar Dec 07 '21 08:12 codebombi

If google translator got you right, issue of not triggering onError callback is that queue interceptor is busy processing your current request and hence blocks any other requests like the one you make when you do dio.fetch. Solution is to use different dio instance when you do dio.fetch

0ttik avatar Dec 15 '21 12:12 0ttik

dio.fetch 要使用新的dio实例

wendux avatar Dec 27 '21 07:12 wendux

那这样的话 example 需要更新一下

gtyhn avatar Dec 27 '21 08:12 gtyhn

Hi same issue for me, OnError is not triggered after a successful refresh token (not always). I will continue to use dio.lock() logic instead of QueuedInterceptorWrapper

atnpem avatar Mar 30 '22 19:03 atnpem

not always but in some case we have facing similar issue. onRequest method of QueuedInterceptorsWrapper triggered but onError not.

fullflash avatar Mar 31 '22 04:03 fullflash

the pr fix it: https://github.com/flutterchina/dio/pull/1457

ipcjs avatar May 30 '22 12:05 ipcjs

使用最新的 4.04 版本

在使用 QueuedInterceptorsWrapper 处理 onError 的 401 状态码,其中刷新 token 成功后使用 dio.fetch 再次请求时,当该请求失败后,则 onError 回调不会触发,造成上层调用方一直处于等待,无法响应,大致代码示例如下:

QueuedInterceptorsWrapper(
    onError: (err, handler) {
      if (err.response?.statusCode == 401) {
        // 刷新 token
        _refreshToken().then((resp) {
          // process token code...

          // token 刷新成功后,继续重发请求,当失败后 onError 不再回调,则上层调用方一直处于等待状态,无法响应
          dio.fetch(err.requestOptions).then(
                (value) => handler.resolve(value),
                onError: (e) => handler.reject(e),
              );
        });
        return;
      }

      handler.next(err);
    },
  );

之前继承 Interceptor 类并使用 lock 的方式没有任何问题,重新请求失败后会再次触发 onError 回调

请问解决了么

supermebing avatar Oct 13 '22 01:10 supermebing

@AlexV525

supermebing avatar Oct 14 '22 02:10 supermebing

@AlexV525

https://github.com/flutterchina/dio/issues/1339#issuecomment-1001400111

AlexV525 avatar Oct 14 '22 03:10 AlexV525

已经使用使用新的dio实例 但在refreshToken也过期后 需要跳转到登录 登录成功后 如果token再过期,onError 回调就不会触发,造成上层调用方一直处于等待

supermebing avatar Oct 14 '22 05:10 supermebing

已经使用使用新的dio实例 但在refreshToken也过期后 需要跳转到登录 登录成功后 如果token再过期,onError 回调就不会触发,造成上层调用方一直处于等待

听起来跟 dio 没有任何关系,单纯的代码没写好。

AlexV525 avatar Oct 14 '22 05:10 AlexV525

已经使用使用新的dio实例 但在refreshToken也过期后 需要跳转到登录 登录成功后 如果token再过期,onError 回调就不会触发,造成上层调用方一直处于等待

听起来跟 dio 没有任何关系,单纯的代码没写好。

但是QueuedInterceptorsWrapper 中 onRequest 是可以监听到的 onError 就不触发了

supermebing avatar Oct 14 '22 07:10 supermebing

我的 app 有完備的測試例 用 QueuedInterceptor 重寫了 Token 相關的代碼後 所有處理連續異常的場景的測試例都超時了

我的感覺是 QueuedInterceptor.onError 裡調用同一個 dio 實例會導致死鎖。

感覺是個設計缺陷: https://github.com/flutterchina/dio/issues/1612

timnew avatar Dec 22 '22 04:12 timnew