interceptResponse method
Runs after the response is received. Return the (possibly modified) response.
Implementation
@override
FutureOr<BaseResponse> interceptResponse({
required BaseResponse response,
}) async {
final request = response.request;
final nf = request == null ? null : _inFlight[request];
if (nf == null) return response;
// The interceptor chain runs before `Response.fromStream`, so
// `interceptResponse` always receives a `StreamedResponse`. To record
// the body we have to drain that one-shot stream ourselves and hand
// back a fresh response carrying the same bytes.
if (!captureResponseBody || response is! StreamedResponse) {
try {
nf.complete(
status: response.statusCode,
responseHeaders: Map<String, String>.from(response.headers),
responseBodySize: response.contentLength,
);
} catch (_) {}
return response;
}
// Buffer the stream once so we can both log the body and hand the
// caller an untouched-looking response. Buffering is what
// `Response.fromStream` already does internally, so for typical JSON
// APIs this isn't extra overhead.
final Uint8List bytes;
try {
bytes = await response.stream.toBytes();
} catch (err) {
try {
nf.fail(err);
} catch (_) {}
rethrow;
}
try {
final body = utf8.decode(bytes, allowMalformed: true);
nf.complete(
status: response.statusCode,
responseHeaders: Map<String, String>.from(response.headers),
responseBody: _cap(body),
responseBodySize: bytes.length,
);
} catch (_) {}
return StreamedResponse(
Stream<List<int>>.value(bytes),
response.statusCode,
contentLength: bytes.length,
request: response.request,
headers: response.headers,
isRedirect: response.isRedirect,
persistentConnection: response.persistentConnection,
reasonPhrase: response.reasonPhrase,
);
}