Fix Flutter Web crash with ANSI colored logs containing invalid UTF-8
Thanks a lot for contributing!
Flutter Web crashes with Bad UTF-8 encoding (U+FFFD; REPLACEMENT CHARACTER) when logging HTTP responses containing replacement characters with ANSI color codes enabled. The browser console's UTF-8 decoder chokes on the combination of ANSI escape sequences and special characters.
Fix: Disable ANSI colors by default on Flutter Web in TalkerFlutter.init().
- Added
_defaultFlutterLogger()helper that setsenableColors: !kIsWeb - Users can still pass a custom logger with colors enabled if desired
// Before: Colors always enabled, crashes on web with certain characters
logger: logger ?? TalkerLogger(output: _defaultFlutterOutput)
// After: Colors disabled on web by default
logger: logger ?? _defaultFlutterLogger()
Fixes #289
Original prompt
This section details on the original issue you should resolve
<issue_title>Flutter Web crash with Talker + Dio logger due to bad UTF-8 / ANSI colored logs</issue_title> <issue_description> Describe the bug When using
TalkerFluttertogether withTalkerDioLoggerin a Flutter Web app, the Flutter Web dev runner sometimes crashes with:
Bad UTF-8 encoding (U+FFFD; REPLACEMENT CHARACTER) found while decoding stringThis happens when a logged HTTP response contains a replacement character (
�) and is printed with ANSI colors and box-drawing characters (│). Mobile builds with the same configuration work fine; the crash is specific to Web + console logging.
To Reproduce Steps to reproduce the behavior:
Configure
TalkerFlutterandTalkerDioLoggerlike this:final Talker appLog = TalkerFlutter.init( settings: TalkerSettings( useHistory: true, maxHistoryItems: 100, useConsoleLogs: kDebugMode || !kIsWeb, ), logger: TalkerLogger( settings: TalkerLoggerSettings( maxLineWidth: 80, enableColors: true, ), ), );final dio = Dio( BaseOptions( baseUrl: 'https://example.com/api/', contentType: 'application/json', connectTimeout: const Duration(seconds: 30), receiveTimeout: const Duration(seconds: 30), ), ); if (kDebugMode) { dio.interceptors.add( TalkerDioLogger( settings: TalkerDioLoggerSettings( printRequestData: true, printResponseData: true, ), talker: appLog, ), ); }Make a request that returns JSON with a field containing a replacement character, for example:
{ "name": "JOHN�DOE" }Run the app on Flutter Web in debug mode, e.g.:
flutter run -d chromeWhen the response is logged, the Web runner crashes with:
Finished with error: Bad UTF-8 encoding (U+FFFD; REPLACEMENT CHARACTER) found while decoding string: [38;5;46m│ "name": "JOHN�DOE",[0m The source bytes were: [27, 91, 51, 56, 59, 53, 59, 52, 54, 109, 226, 148, 130, 32, 32, 32, 32, 32, 32, 32, 34, 110, 97, 109, 101, 34, 58, 32, 34, 74, 79, 72, 78, 239, 191, 189, 68, 79, 69, 34, 44, 27, 91, 48, 109, 10]
Expected behavior Talker / TalkerDioLogger should not cause the Flutter Web dev runner to crash, even if the response body contains invalid/partial UTF-8 or replacement characters. At worst, logs on Web should be safely sanitized (for example, without ANSI color codes or truncated) so that console output doesn’t break UTF-8 decoding.
Screenshots N/A – this is a console / dev-runner crash, see log output above.
Desktop (please complete the following information):
- OS: Windows 10 22H2, macOS Sonoma 14.2
- Browser: Chrome (via
flutter run -d chrome)- Version: 143.0.7499.40
Smartphone (please complete the following information):
N/A – issue is specific to Flutter Web.
Additional context
The problem only appears when:
useConsoleLogsis enabled on WebenableColorsistrueTalkerDioLoggerprints the response body with problematic characters.Workaround I’m currently using:
final Talker appLog = TalkerFlutter.init( settings: TalkerSettings( useHistory: true, maxHistoryItems: 100, useConsoleLogs: kDebugMode && !kIsWeb, // no console logs on Web ), logger: TalkerLogger( settings: TalkerLoggerSettings( maxLineWidth: 80, enableColors: !kIsWeb, // no ANSI colors on Web ), ), );if (kDebugMode) { dio.interceptors.add( TalkerDioLogger( settings: TalkerDioLoggerSettings( printRequestData: !kIsWeb, printResponseData: !kIsWeb, // don’t print body on Web ), talker: appLog, ), ); }With this configuration the crash no longer happens on Web.
I’d be happy to open a PR to:
- adjust defaults for Web (e.g. disable colors / console logs by default on
kIsWeb), or- add a documented “web-safe” configuration/example in the README.
Environment:
- Flutter: 3.38.1
- Dart: 3.10.0
- talker: 5.0.2
- talker_flutter: 5.0.2
- talker_dio_logger: 5.0.2 </issue_description>
Comments on the Issue (you are @copilot in this section)
- Fixes Frezyx/talker#448
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.