Search code examples
flutterdartinterceptordio

Error: Bad state: The FormData has already been finalized. This typically means you are using the same FormData in repeated requests


Am trying to upload an image to server, but when its making the request its calls the interceptor to refreshToken after getting the token it will throw this error:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: DioException [unknown]: null E/flutter ( 5915): Error: Bad state: The FormData has already been finalized. This typically means you are using the same FormData in repeated requests.

Here is the code:

final token = storageService.getAccessToken();
String fileName = photo.path.split('/').last;
Map<String, String> headers = <String, String>{
  'Accept': 'application/json',
  'content-type': 'multipart/form-data',
  'Authorization': token!,
};

final formData = dios.FormData.fromMap({
  "image": await dios.MultipartFile.fromFile(
    photo.path,
    filename: fileName,
  ),
});
final response = await dio.patch(
  "${AppConfig.endPoint}api/upload-picture",
  data: formData,
  options: dios.Options(
    headers: headers,
  ),
);

if (response.statusCode == 200) {
  return true;
} else if (response.data['code'] == 'token_not_valid') {
  final anotherformData = dios.FormData.fromMap({
    "profile_picture": await dios.MultipartFile.fromFile(
      photo.path,
      filename: fileName,
    ),
  });
  await dio.patch(
    "${AppConfig.endPoint}api/upload-picture",
    data: anotherformData,
    options: dios.Options(
      headers: headers,
    ),
  );
} else {
  throw Exception(response.statusMessage);
}
getUserProfile();
return true;}

The InterceptorsWrapper

dio.interceptors.addAll([
  PrettyDioLogger(
      requestHeader: true,
      requestBody: true,
      responseBody: true,
      responseHeader: false,
      error: true,
      compact: true,
      request: true,
      maxWidth: 150),

  dios.InterceptorsWrapper(
    onError: (dios.DioException e, handler) async {
      if (e.response?.data['code'] == 'token_not_valid') {
        // If a 401 response is received, refresh the access token
        RefreshTokenResponse? newAccessToken = await refreshToken(
            RefreshTokenBody(
                refresh: storageService.getRefreshToken() ?? ''));

        //Save the  new token and refresh token here
        storageService.setAccessToken(newAccessToken?.access ?? '');

        // Update the request header with the new access token
        e.requestOptions.headers['Authorization'] =
            'Bearer ${newAccessToken?.access}';

        // Repeat the request with the updated header
        return handler.resolve(await dio.fetch(e.requestOptions));
      }
      return handler.next(e);
    },
  ),
]);

Any Idea on how i fix this issue please. Thank you.

enter image description here


Solution

  • I was able to fix the issue, what i did was to make sure i do a check if the token has expired or not before making the request to upload the photo, with the help of this package jwt_decode: https://pub.dev/packages/jwt_decode