truncateBody function
Truncates data's string form to maxLength characters, appending a
marker with the original length, so a single large body can't dominate
the in-memory capture buffers.
For non-string data (typically a JSON-decoded Map/List), that
string form is prettyFormatBody's indented rendering, not
Object.toString — a truncated Map/List can never be valid JSON
again (the cut necessarily leaves it unbalanced), so once
truncated it can never be pretty-printed again either; deciding
the cut point against the plain toString() (Dart's {key: value} syntax, no indentation) would have permanently frozen a
large body into that single unreadable line. Pretty-printing
first means the visible, truncated prefix is still properly
indented, multi-line JSON, right up to the cutoff.
Raw bytes and FormData are summarized unconditionally, before
the length check — prettyFormatBody's summary for either is
already short regardless of the underlying payload's actual size
(a multi-megabyte download summarizes just as compactly as a
tiny one), so measuring that against maxLength would never
trip, and the raw bytes (or a live multipart stream) would sit in
the in-memory capture buffer at full size indefinitely — exactly
what this function exists to prevent.
Implementation
Object? truncateBody(Object? data, int maxLength) {
if (data == null) return null;
if (data is Uint8List || data is FormData) return prettyFormatBody(data);
final asString = data is String ? data : prettyFormatBody(data);
if (asString.length <= maxLength) return data;
return '${asString.substring(0, maxLength)}… [truncated, ${asString.length} chars total]';
}