Перехватчик Flutter Dio: ошибка DioError [Ошибка DioErrorType.ПО УМОЛЧАНИЮ]: Плохое состояние: не удается завершить завершенный многокомпонентный файл

#flutter #dio

#ошибка #dio

Вопрос:

Привет, я пытаюсь обновить логику в перехватчике Dio. он отлично работает для параметров тела json, но он выдает ошибку DioError [Ошибка DioErrorType .ПО УМОЛЧАНИЮ]: Плохое состояние: не удается завершить завершенный многокомпонентный файл при попытке загрузки изображений.

 onError: (DioError error) async {
      // Do something with response error
      if (error.response?.statusCode == 401) {
        // _dio.interceptors.requestLock.lock();
        Response response;
        RequestOptions options = error.response.request;
        response = await _dio
            .post('/user/refresh', data: {"refreshToken": _refreshToken});
    if (response.statusCode == 200) {
      final userData = json.encode(
        {
          'token': response.data["accessToken"],
          'tokenType': _tokenType,
          'refreshToken': response.data["refreshToken"]
        },
      );
      prefs.setString('userData', userData);
      
        options.data = formData;
      }
      options.headers["Authorization"] =
          "$_tokenType ${response.data['accessToken']}";
      return await _dio.request(options.path, options: options);
    } else {
      throw error;
    }
  

Комментарии:

1. У меня точно такая же проблема. Есть какие-либо успехи в его решении?

Ответ №1:

Я собрал обходной путь для этой проблемы, который в основном состоит из перестройки FormData перед повторной попыткой. Это немного странно, но работает. Я начинаю с передачи любой информации, которая мне нужна для реконструкции, через «дополнительную» карту в параметрах запроса, чтобы перехватчик имел к ней доступ. Вот некоторый псевдокод:

 //original request
dioResponse = await dio.post(
  'http://my/api/endpoint',
  data: myOriginalFormData,
  options: Options(
    headers: myHeaders,
    extra: {'pathToMyFile': pathToMyFile},
  ),
);

//and in my interceptor I use it to construct a fresh FormData that has not been finalized
final FormData newFormData = FormData.fromMap({
  'file': await MultipartFile.fromFile(
       requestOptions.extra['pathToMyFile'],
       contentType: MediaType('application/json', 'json')),
});

//retry with the fresh FormData
return dio.request(
  requestOptions.path,
  data: newFormData,
  options: requestOptions,
  cancelToken: requestOptions.cancelToken,
  onReceiveProgress: requestOptions.onReceiveProgress,
  onSendProgress: requestOptions.onSendProgress,
  queryParameters: requestOptions.queryParameters,
);
  

У кого-нибудь есть мысли об этом подходе? Какие-либо серьезные недостатки?

Ответ №2:

Похоже, проблема в отправке одних и тех же данных формы без последнего запроса finlize, решила ту же проблему таким образом :

   static final Dio dio2 = Dio();

  static Future<dynamic> _retry(RequestOptions requestOptions) async {
    final options = new Options(
      method: requestOptions.method,
      headers: (await getHeaders()),
    );

    options.responseType = (ResponseType.json);
    Map<String, String>? data;
    try {
      data = Map.fromEntries(requestOptions.data?.fields);
    } catch (e) {}
    var res = dio2.request<dynamic>(
        requestOptions.baseUrl   requestOptions.path,
        data: data == null ? null : FormData.fromMap(data),
        queryParameters: requestOptions.queryParameters,
        options: options);

    return res;
  }
  

используйте его в блоке, где вы хотите повторно отправить тот же запрос таким образом :

 handler.resolve(await _retry(response.requestOptions));