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

[fresh_dio] Recommended way to log refresh and retry requests #93

Closed
LukasMirbt opened this issue Sep 1, 2023 · 3 comments
Closed

[fresh_dio] Recommended way to log refresh and retry requests #93

LukasMirbt opened this issue Sep 1, 2023 · 3 comments

Comments

@LukasMirbt
Copy link
Contributor

What is the recommended way to log refresh and retry requests? Or adding other kinds of interceptors to those requests.

There is currently a pitfall that causes requests to stall indefinitely when passing the same httpClient into the Fresh constructor that later has the Fresh interceptor attached to it.

Could it be a good idea to rename the parameter, adding documentation or to add an assert that the Dio instance passed in should not have a Fresh interceptor?

@Kiura
Copy link

Kiura commented Jan 29, 2024

@LukasMirbt did you find a way fix this?

@felangel
Copy link
Owner

This should be fixed by #98

@LukasMirbt
Copy link
Contributor Author

#98 prevents accidentally causing a loop but does not address how to log refresh and retry requests.

I currently have the following setup:

  AppClient({
    required String baseUrl,
    required TokenStorage<Tokens> tokenStorage,
    Dio? client,
    Dio? retryClient,
    TokenApi? tokenApi,
  }) {
    final loggingInterceptor = PrettyDioLogger(
      responseBody: false,
      logPrint: (object) => log(
        object.toString(),
      ),
    );

    http = client ?? Dio();
    _retryClient = retryClient ?? Dio();
    _tokenApi = tokenApi ?? TokenApi(_retryClient, AppLogging.logger);

    _fresh = Fresh(
      httpClient: _retryClient,
      tokenStorage: tokenStorage,
      tokenHeader: (tokens) => {
        'Authorization': 'Bearer ${tokens.access}',
      },
      shouldRefresh: _tokenApi.shouldRefresh,
      refreshToken: (tokens, _) async {
        Tokens refreshedTokens;

        try {
          refreshedTokens = await _tokenApi.refresh(tokens);
        } catch (error, stackTrace) {
          Error.throwWithStackTrace(
            TokenRefreshFailure(error),
            stackTrace,
          );
        }

        return refreshedTokens;
      },
    );

    final baseOptions = BaseOptions(
      validateStatus: (_) => true,
      baseUrl: baseUrl,
    );

    http.options = baseOptions;
    _retryClient.options = baseOptions;

    http
      ..interceptors.add(loggingInterceptor)
      ..interceptors.add(_fresh)
      ..addSentry();

    _retryClient
      ..interceptors.add(loggingInterceptor)
      ..addSentry();
  }

This works but it's a bit ugly.
It would be ideal to be able to reuse the same Dio client for refresh/retries so the same BaseOptions and logging is applied.
Do you think that makes sense/have you solved this in another way? @felangel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants