Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't finalize a finalized MultipartFile #52

Open
MekniWassime opened this issue Aug 27, 2021 · 6 comments
Open

Can't finalize a finalized MultipartFile #52

MekniWassime opened this issue Aug 27, 2021 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@MekniWassime
Copy link

MekniWassime commented Aug 27, 2021

My team and i are working on a mobile app that sometimes requires us to send multiple images to a nodejs server using FormData and MutipartFiles (part of the dio package) and recently we had to transition from sessions and cookies to Jwt tokens. and the transition was really seamless thanks to your package that honestly saved me days of work at least
but i ran into a problem and here's the scenario for simplicity

  • i send a post request where data is of type FormData that contains multiple files or MultipartFiles
  • the token has expired so your package requests a new accessToken (as far as i understand)
  • a new accessToken is received and the request is resent
  • a Dio error is thrown DioError [DioErrorType.other]: Bad state: Can't finalize a finalized MultipartFile. (i will put the entire error message below)

after doing some research on the matter i found out that you have to basically make a new FormData object out of the old FormData if you want to resend a request
a link of the most promising solution i found cfug/dio#482
here is how i implemented your interceptor

static  final _fresh = Fresh.oAuth2(
    tokenStorage: PersistantTokenStorage(),
    refreshToken: (token, client) async {
    print('refreshing token...');
    try {
	    var response = await AuthService.getAcessToken(token?.refreshToken);
	    print("refresh response");
	    print(response);
	    String? newAccessToken = response['accessToken'];
	    if (newAccessToken == null)
		    throw RevokeTokenException();
	    return OAuth2Token(
		    accessToken: newAccessToken,
		    refreshToken: token?.refreshToken,
		   );
	    } catch (e) {
		    print(e);
		    throw RevokeTokenException();
	    }
    },
);

and here's the full error code with some of the prints that i did included (note that aside from MultipartFiles no other problem has occured

I/flutter (10036): refreshing token...    
I/flutter (10036): refresh token response = {accessToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiNjEwNjk4YmUzMDUxNTEzNjg4ZTRmMWIyIiwiZW1haWwiOiJ0dW5pc2lhbmNhbXBlcnNAZ21haWwuY29tIn0sImlhdCI6MTYzMDA5MTU1NSwiZXhwIjoxNjMwMDkxNTg1fQ.mU32DL3-b-pq_OyEyA4gdnhTrlE0tgXwSGjWGN-pfug}
I/flutter (10036): refresh response
I/flutter (10036): {accessToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiNjEwNjk4YmUzMDUxNTEzNjg4ZTRmMWIyIiwiZW1haWwiOiJ0dW5pc2lhbmNhbXBlcnNAZ21haWwuY29tIn0sImlhdCI6MTYzMDA5MTU1NSwiZXhwIjoxNjMwMDkxNTg1fQ.mU32DL3-b-pq_OyEyA4gdnhTrlE0tgXwSGjWGN-pfug}
I/flutter (10036): saving token
I/flutter (10036): DioError [DioErrorType.other]: Bad state: Can't finalize a finalized MultipartFile.
I/flutter (10036): #0 FormData.finalize
package:dio/src/form_data.dart:134
I/flutter (10036): #1 DioMixin._transformData
package:dio/src/dio_mixin.dart:706
I/flutter (10036): #2 DioMixin._dispatchRequest
package:dio/src/dio_mixin.dart:631
I/flutter (10036): #3 DioMixin.fetch.<anonymous closure>
package:dio/src/dio_mixin.dart:585
I/flutter (10036): #4 DioMixin.fetch._requestInterceptorWrapper.<anonymous closure>.<anonymous closure>.<anonymous closure>
package:dio/src/dio_mixin.dart:502
I/flutter (10036): #5 DioMixin.checkIfNeedEnqueue
package:dio/src/dio_mixin.dart:795
I/flutter (10036): #6 DioMixin.fetch._requestInterceptorWrapper.<anonymous closure>.<anonymous closure>
package:dio/src/dio_mixin.dart:500
I/flutter (10036): #7 new Future.<anonymous closure> (dart:async/future.dart:174:37)
I/flutter (10036): #8 _rootRun (dart:async/zone.dart:1346:47)
I/flutter (10036): #9 _CustomZone.run (dart:async/zone.dart:1258:19)
I/flutter (10036): #10 _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
I/flutter (10036): #11 _CustomZone.bindCallbackGuarded.<anonymous clos

some information about the environment and versions used

environment:    
    sdk: ">=2.12.0 <3.0.0"
dependencies:
    dio: ^4.0.0
    fresh_dio: ^0.3.1

if more information could be provided i d be more than happy to provide them

@felangel felangel self-assigned this Aug 27, 2021
@felangel
Copy link
Owner

Hi @MekniWassime 👋
Thanks so much for opening an issue and for the detailed overview of the issue! I’ll take a closer look ASAP but I’m the meantime if you have a minimal reproduction sample that would be super helpful, thanks! 🙏💙

@felangel felangel added the bug Something isn't working label Aug 27, 2021
@MekniWassime
Copy link
Author

Thank you for the reply, although i m currently quite busy i will take a shot at making a reproduction sample
No promises though hope you understand

@TrGiLong
Copy link

TrGiLong commented Oct 23, 2021

Hi,

I have the same problem when users upload multipart files with the expired token. By resending a request with a refreshed token the user will receive the Bad state: Can't finalize a finalized MultipartFile. because fresh_dio copies the closed data stream from the first request.

My solution will be recreating a new stream during sending a second request. It will be hard since data property of Request class is dynamic and I'm not sure the data structure for all cases.

In my fresh_dio_next package I have extended this package by adding extra checking of the token before sending . So the request will be processed the most of time. It's also should prevent sending a first invalid request with large data, which always will be failed and resending (Correct me if I'm wrong :D).

@enioluciano
Copy link

enioluciano commented Dec 1, 2021

Hi, @felangel
I'm facing same problem. When I upload photos in API, i get same error.

@faithomotoso
Copy link

@enioluciano Do you have a refresh token implementation?

@jeankpoti
Copy link

jeankpoti commented Jun 23, 2022

You can just reset the list in which you are storing the multipartfile after the request is made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants