using System.Net;
using System.Net.Http;
namespace ModelContextProtocol;
///
/// Extension methods for .
///
internal static class HttpResponseMessageExtensions
{
private const int MaxResponseBodyLength = 1024;
///
/// Throws an if the property is .
/// Unlike , this method includes the response body in the exception message
/// to help diagnose issues when the server returns error details in the response body.
///
/// The HTTP response message to check.
/// The token to monitor for cancellation requests.
/// A task that represents the asynchronous operation.
/// The response status code does not indicate success.
public static async Task EnsureSuccessStatusCodeWithResponseBodyAsync(this HttpResponseMessage response, CancellationToken cancellationToken = default)
{
if (!response.IsSuccessStatusCode)
{
string? responseBody = null;
try
{
using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
cts.CancelAfter(TimeSpan.FromSeconds(5));
responseBody = await response.Content.ReadAsStringAsync(cts.Token).ConfigureAwait(false);
if (responseBody.Length > MaxResponseBodyLength)
{
responseBody = responseBody.Substring(0, MaxResponseBodyLength) + "...";
}
}
catch
{
// Ignore all errors reading the response body (e.g., stream closed, timeout, cancellation) - we'll throw without it.
}
throw CreateHttpRequestException(response, responseBody);
}
}
///
/// Creates an for a non-success response, including the response body in the message.
///
/// The HTTP response message.
/// The response body content, if available.
/// An with the response details.
public static HttpRequestException CreateHttpRequestException(HttpResponseMessage response, string? responseBody)
{
int statusCodeInt = (int)response.StatusCode;
string message = string.IsNullOrEmpty(responseBody)
? $"Response status code does not indicate success: {statusCodeInt} ({response.ReasonPhrase})."
: $"Response status code does not indicate success: {statusCodeInt} ({response.ReasonPhrase}). Response body: {responseBody}";
#if NET
return new HttpRequestException(message, inner: null, response.StatusCode);
#else
return new HttpRequestException(message);
#endif
}
}