You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用dio与pretty_dio_logger出现递归打印错误求助

解决Dio网络请求日志递归错误:Recursion during print() call. Abort adding print() call as Breadcrumb.

问题描述

在Flutter项目中使用Dio实现网络请求,通过pretty_dio_logger记录API请求与响应时,出现错误提示:Recursion during print() call. Abort adding print() call as Breadcrumb.,该日志替代了原本的API请求和响应日志。改用dio.LogInterceptor后问题依然存在。

依赖配置

dependencies:
  dio: ^5.5.0+1
  pretty_dio_logger: ^1.3.1

网络请求服务代码

import 'dart:async';
import 'package:dio/dio.dart';
import 'package:gpace_app/core/network/authorization_interceptor.dart';
import 'package:gpace_app/flavors.dart';
import 'package:gpace_app/services/logger_service.dart';
import 'package:intl/intl.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';

class NetworkService {
  NetworkService(
    this._dio,
  ) {
    final intl = Intl();

    _dio.options.baseUrl = F.baseUrl;
    _dio.options.contentType = 'application/json';
    _dio.options.headers = {
      'lang': intl.locale,
      'timeOffset': 0,
    };
    _dio.options.connectTimeout = const Duration(seconds: 20);
    _dio.options.receiveTimeout = const Duration(seconds: 20);

    _dio.options.validateStatus = (status) {
      return status! < 500;
    };
    _dio.interceptors.add(AuthorizationInterceptor());
    _dio.interceptors.add(
      PrettyDioLogger(
        responseBody: true,
        requestBody: true,
        responseHeader: false,
      ),
    );
    _dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (options, handler) {
          handler.next(options);
        },
        onResponse: (response, handler) async {
          handler.next(response);
        },
        onError: (DioException error, handler) {
          if (error.response != null) {
            handler.resolve(
              Response(
                requestOptions: error.requestOptions,
                statusCode: error.response!.statusCode,
                data: error.response!.data,
                headers: error.response!.headers,
                statusMessage: error.message,
              ),
            );
          } else {
            handler.next(error);
          }
        },
      ),
    );
  }

  final Dio _dio;

  Future<Response<T>> get<T>(
    String path, {
    Map<String, dynamic>? queryParameters,
    Options? options,
  }) async {
    try {
      return await _dio.get<T>(
        path,
        queryParameters: queryParameters,
        options: options,
      );
    } on DioException catch (e) {
      _logError(e);
      rethrow;
    }
  }

  void _logError(DioException error) {
    LoggerService.logError(
      'DioError: ${error.message}',
    );
    if (error.response != null) {
      LoggerService.logError('DioError Response: ${error.response?.data}');
    }
  }
}

Flutter Doctor结果

omer@% flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.27.1, on macOS 15.1.1 24B91 darwin-arm64, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.2)
[✓] VS Code (version 1.84.0)
[✓] Connected device (3 available)
    ! Error: Browsing on the local area network for Iphone 11 Omer. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)
    ! Error: Browsing on the local area network for Ömer’s iPhone. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources

解决方案

  • 排查LoggerService递归调用:_logError方法中调用的LoggerService.logError可能与Dio拦截器的日志输出形成递归循环。检查LoggerService内部是否使用了print或其他会触发Dio拦截的操作,导致日志调用触发拦截器,进而再次调用日志方法。
  • 调整拦截器顺序:将日志拦截器(PrettyDioLogger/LogInterceptor)放在所有拦截器的最后。当前代码中自定义错误拦截器在日志拦截器之后添加,若错误处理逻辑触发日志,会被日志拦截器捕获引发递归。调整顺序后,日志拦截器只会处理原始请求/响应,不会捕获后续错误处理中的日志操作。
  • 临时禁用LoggerService调用:注释_logError中的LoggerService.logError调用,测试是否仍出现递归错误。若问题消失,说明是LoggerService与Dio日志的冲突,需修改LoggerService实现,比如添加递归保护(如标记当前是否正在日志输出,避免重复调用)。
  • 检查AuthorizationInterceptor:确认AuthorizationInterceptor中是否存在日志输出或刷新token时发起新网络请求的逻辑,新请求被日志拦截器捕获后可能形成循环。若有此类逻辑,需添加判断避免递归触发。

内容的提问来源于stack exchange,提问作者Ömer Faruk Genc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:39:58