Include response body in HttpRequestException for transport client errors (#1193)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
This commit is contained in:
Copilot 2026-01-29 17:23:21 -05:00 • committed by GitHub
commit 7c85ac6706
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 149 additions and 6 deletions

View file

@ -88,16 +88,19 @@ internal sealed partial class SseClientSessionTransport : TransportBase
if (!response.IsSuccessStatusCode)
{
// Read the response body once to include in both logging and exception
string responseBody = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
if (_logger.IsEnabled(LogLevel.Trace))
{
LogRejectedPostSensitive(Name, messageId, await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false));
LogRejectedPostSensitive(Name, messageId, responseBody);
}
else
{
LogRejectedPost(Name, messageId);
}
response.EnsureSuccessStatusCode();
throw HttpResponseMessageExtensions.CreateHttpRequestException(response, responseBody);
}
}
@ -148,7 +151,7 @@ internal sealed partial class SseClientSessionTransport : TransportBase
using var response = await _httpClient.SendAsync(request, message: null, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
await response.EnsureSuccessStatusCodeWithResponseBodyAsync(cancellationToken).ConfigureAwait(false);
using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);

View file

@ -61,7 +61,7 @@ internal sealed partial class StreamableHttpClientSessionTransport : TransportBa
{
// Immediately dispose the response. SendHttpRequestAsync only returns the response so the auto transport can look at it.
using var response = await SendHttpRequestAsync(message, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
await response.EnsureSuccessStatusCodeWithResponseBodyAsync(cancellationToken).ConfigureAwait(false);
}
// This is used by the auto transport so it can fall back and try SSE given a non-200 response without catching an exception.