Flutter使用dio与pretty_dio_logger出现递归打印错误求助
问题描述
在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
相关产品推荐
相关产品推荐

