#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));