handleError method

Future<void> handleError(
  1. DioError e,
  2. ErrorInterceptorHandler handler
)

Implementation

Future<void> handleError(DioError e, ErrorInterceptorHandler handler) async {
  var retryCount = 0;
  final maxRetries = 5;

  while (retryCount < maxRetries) {
    try {
      var dio2 = Dio();
      final prefs = await SharedPreferences.getInstance();
      var rt = prefs.getString(prefixRefreshToken);
      var ua = prefs.getString("ua");
      final info = await PackageInfo.fromPlatform();

      Map<String, Object?>? keySet;
      var headers = {
        "User-Agent": ua,
        "x-app-id": info.packageName,
        "accept": defaultType,
        Headers.contentTypeHeader: defaultType
      };

      var dataRefresh = {"refreshToken": rt};
      if (commonEncMode) {
        keySet = await payloadEnc.generateKeyPair();
        var encryptData = await payloadEnc.encryptData(dataRefresh, keySet);
        var newPayload = {"cipherText": encryptData};
        dataRefresh = newPayload;
        final base64Str = buildEncKeyHeader(keySet);
        headers = {...headers, encryptionKeyLabel: base64Str};
      }

      var response = await dio2.request(
        appUrl + "/services/auth",
        data: dataRefresh,
        options: Options(method: "PATCH", headers: headers),
      );

      if (commonEncMode) {
        var ct = chiperType.fromJson(response.data);
        var decrypt = await payloadEnc.decryptData(ct.cipherText!, keySet!);
        var jsondecode = json.decode(decrypt);
        response.data = jsondecode;
      }

      var res = RefreshTokenResponse.fromJson(response.data);

      prefs.setString(prefixRefreshToken, res.data!.attributes!.refreshToken!);
      prefs.setString(prefixAccessToken, res.data!.attributes!.accessToken!);
      prefs.setString(prefixExpiryToken, res.data!.attributes!.expiry!);

      var atNew = res.data!.attributes!.accessToken!;

      e.requestOptions.headers["Authorization"] = "Bearer " + atNew;
      final opts = new Options(
          method: e.requestOptions.method, headers: e.requestOptions.headers);
      final cloneReq = await dio.request(e.requestOptions.path,
          options: opts,
          data: e.requestOptions.data,
          queryParameters: e.requestOptions.queryParameters);
      return handler.resolve(cloneReq);
    } on DioError catch (err) {
      retryCount++;
      if (retryCount == maxRetries) {
        var title = err.response?.data["errors"]?[0];
        var evtCb = opts!.options?.eventCallback;
        if (title?["code"] == "IVREF") {
          evtCb({"name": "invalid_refresh_token"});
        } else if (title?["code"] == "BADAUTH") {
          evtCb({"name": "invalid_access_token"});
        }
        return handler.reject(err);
      }
      await Future.delayed(Duration(seconds: 1)); // Add delay between retries
    }
  }
}