Skip to content

Commit c0d0b1a

Browse files
authored
React to HttpRequestError API changes (#89124)
* React to HttpRequestError API changes * Use InvalidResponse for net_http_invalid_response_multiple_status_codes * Use HttpRequestError.Unknown for the rest * Add simple tests for the HttpRequestError property * Fix the inner exception being removed by mistake
1 parent 6cd933a commit c0d0b1a

File tree

13 files changed

+75
-58
lines changed

13 files changed

+75
-58
lines changed

src/libraries/System.Net.Http/ref/System.Net.Http.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,8 @@ public HttpRequestException() { }
272272
public HttpRequestException(string? message) { }
273273
public HttpRequestException(string? message, System.Exception? inner) { }
274274
public HttpRequestException(string? message, System.Exception? inner, System.Net.HttpStatusCode? statusCode) { }
275-
public HttpRequestException(string? message, System.Exception? inner = null, System.Net.HttpStatusCode? statusCode = null, System.Net.Http.HttpRequestError? httpRequestError = null) { }
276-
public System.Net.Http.HttpRequestError? HttpRequestError { get { throw null; } }
275+
public HttpRequestException(System.Net.Http.HttpRequestError httpRequestError, string? message = null, System.Exception? inner = null, System.Net.HttpStatusCode? statusCode = null) { }
276+
public System.Net.Http.HttpRequestError HttpRequestError { get { throw null; } }
277277
public System.Net.HttpStatusCode? StatusCode { get { throw null; } }
278278
}
279279
public partial class HttpRequestMessage : System.IDisposable

src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Buffers;
55
using System.Diagnostics;
66
using System.Diagnostics.CodeAnalysis;
7+
using System.Globalization;
78
using System.IO;
89
using System.Net.Http.Headers;
910
using System.Text;
@@ -608,7 +609,7 @@ private bool CreateTemporaryBuffer(long maxBufferSize, out MemoryStream? tempBuf
608609
// This should only be hit when called directly; HttpClient/HttpClientHandler
609610
// will not exceed this limit.
610611
throw new ArgumentOutOfRangeException(nameof(maxBufferSize), maxBufferSize,
611-
SR.Format(System.Globalization.CultureInfo.InvariantCulture,
612+
SR.Format(CultureInfo.InvariantCulture,
612613
SR.net_http_content_buffersize_limit, HttpContent.MaxBufferSize));
613614
}
614615

@@ -720,7 +721,7 @@ internal static Exception WrapStreamCopyException(Exception e)
720721
{
721722
Debug.Assert(StreamCopyExceptionNeedsWrapping(e));
722723
HttpRequestError error = e is HttpIOException ioEx ? ioEx.HttpRequestError : HttpRequestError.Unknown;
723-
return new HttpRequestException(SR.net_http_content_stream_copy_error, e, httpRequestError: error);
724+
return new HttpRequestException(error, SR.net_http_content_stream_copy_error, e);
724725
}
725726

726727
private static int GetPreambleLength(ArraySegment<byte> buffer, Encoding encoding)
@@ -835,7 +836,7 @@ private static async Task<TResult> WaitAndReturnAsync<TState, TResult>(Task wait
835836

836837
private static HttpRequestException CreateOverCapacityException(long maxBufferSize)
837838
{
838-
return new HttpRequestException(SR.Format(System.Globalization.CultureInfo.InvariantCulture, SR.net_http_content_buffersize_exceeded, maxBufferSize), httpRequestError: HttpRequestError.ConfigurationLimitExceeded);
839+
return new HttpRequestException(HttpRequestError.ConfigurationLimitExceeded, SR.Format(CultureInfo.InvariantCulture, SR.net_http_content_buffersize_exceeded, maxBufferSize));
839840
}
840841

841842
internal sealed class LimitMemoryStream : MemoryStream

src/libraries/System.Net.Http/src/System/Net/Http/HttpRequestException.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ public HttpRequestException(string? message, Exception? inner, HttpStatusCode? s
3838
/// <summary>
3939
/// Initializes a new instance of the <see cref="HttpRequestException" /> class with a specific message an inner exception, and an HTTP status code and an <see cref="HttpRequestError"/>.
4040
/// </summary>
41+
/// <param name="httpRequestError">The <see cref="HttpRequestError"/> that caused the exception.</param>
4142
/// <param name="message">A message that describes the current exception.</param>
4243
/// <param name="inner">The inner exception.</param>
4344
/// <param name="statusCode">The HTTP status code.</param>
44-
/// <param name="httpRequestError">The <see cref="HttpRequestError"/> that caused the exception.</param>
45-
public HttpRequestException(string? message, Exception? inner = null, HttpStatusCode? statusCode = null, HttpRequestError? httpRequestError = null)
45+
public HttpRequestException(HttpRequestError httpRequestError, string? message = null, Exception? inner = null, HttpStatusCode? statusCode = null)
4646
: this(message, inner, statusCode)
4747
{
4848
HttpRequestError = httpRequestError;
@@ -51,10 +51,7 @@ public HttpRequestException(string? message, Exception? inner = null, HttpStatus
5151
/// <summary>
5252
/// Gets the <see cref="Http.HttpRequestError"/> that caused the exception.
5353
/// </summary>
54-
/// <value>
55-
/// The <see cref="Http.HttpRequestError"/> or <see langword="null"/> if the underlying <see cref="HttpMessageHandler"/> did not provide it.
56-
/// </value>
57-
public HttpRequestError? HttpRequestError { get; }
54+
public HttpRequestError HttpRequestError { get; }
5855

5956
/// <summary>
6057
/// Gets the HTTP status code to be returned with the exception.
@@ -66,8 +63,8 @@ public HttpRequestException(string? message, Exception? inner = null, HttpStatus
6663

6764
// This constructor is used internally to indicate that a request was not successfully sent due to an IOException,
6865
// and the exception occurred early enough so that the request may be retried on another connection.
69-
internal HttpRequestException(string? message, Exception? inner, RequestRetryType allowRetry, HttpRequestError? httpRequestError = null)
70-
: this(message, inner, httpRequestError: httpRequestError)
66+
internal HttpRequestException(HttpRequestError httpRequestError, string? message, Exception? inner, RequestRetryType allowRetry)
67+
: this(httpRequestError, message, inner)
7168
{
7269
AllowRetry = allowRetry;
7370
}

src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ private static async Task<HttpResponseMessage> SendWithNtAuthAsync(HttpRequestMe
209209
{
210210
isNewConnection = false;
211211
connection.Dispose();
212-
throw new HttpRequestException(SR.Format(SR.net_http_authvalidationfailure, statusCode), null, HttpStatusCode.Unauthorized, HttpRequestError.UserAuthenticationError);
212+
throw new HttpRequestException(HttpRequestError.UserAuthenticationError, SR.Format(SR.net_http_authvalidationfailure, statusCode), statusCode: HttpStatusCode.Unauthorized);
213213
}
214214
break;
215215
}

src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public static async ValueTask<SslStream> EstablishSslConnectionAsync(SslClientAu
8989
throw CancellationHelper.CreateOperationCanceledException(e, cancellationToken);
9090
}
9191

92-
HttpRequestException ex = new HttpRequestException(SR.net_http_ssl_connection_failed, e, httpRequestError: HttpRequestError.SecureConnectionError);
92+
HttpRequestException ex = new HttpRequestException(HttpRequestError.SecureConnectionError, SR.net_http_ssl_connection_failed, e);
9393
if (request.IsExtendedConnectRequest)
9494
{
9595
// Extended connect request is negotiating strictly for ALPN = "h2" because HttpClient is unaware of a possible downgrade.
@@ -139,7 +139,7 @@ internal static Exception CreateWrappedException(Exception exception, string hos
139139
{
140140
return CancellationHelper.ShouldWrapInOperationCanceledException(exception, cancellationToken) ?
141141
CancellationHelper.CreateOperationCanceledException(exception, cancellationToken) :
142-
new HttpRequestException($"{exception.Message} ({host}:{port})", exception, RequestRetryType.RetryOnNextProxy, DeduceError(exception));
142+
new HttpRequestException(DeduceError(exception), $"{exception.Message} ({host}:{port})", exception, RequestRetryType.RetryOnNextProxy);
143143

144144
static HttpRequestError DeduceError(Exception exception)
145145
{

src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2104,11 +2104,11 @@ await Task.WhenAny(requestBodyTask, responseHeadersTask).ConfigureAwait(false) =
21042104
}
21052105
catch (HttpIOException e)
21062106
{
2107-
throw new HttpRequestException(e.Message, e, httpRequestError: e.HttpRequestError);
2107+
throw new HttpRequestException(e.HttpRequestError, e.Message, e);
21082108
}
21092109
catch (Exception e) when (e is IOException || e is ObjectDisposedException || e is InvalidOperationException)
21102110
{
2111-
throw new HttpRequestException(SR.net_http_client_execution_error, e, httpRequestError: HttpRequestError.Unknown);
2111+
throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_client_execution_error, e);
21122112
}
21132113
}
21142114

@@ -2205,7 +2205,7 @@ internal void Trace(int streamId, string message, [CallerMemberName] string? mem
22052205

22062206
[DoesNotReturn]
22072207
private static void ThrowRetry(string message, Exception? innerException = null) =>
2208-
throw new HttpRequestException(message, innerException, allowRetry: RequestRetryType.RetryOnConnectionFailure);
2208+
throw new HttpRequestException(HttpRequestError.Unknown, message, innerException, RequestRetryType.RetryOnConnectionFailure);
22092209

22102210
private static Exception GetRequestAbortedException(Exception? innerException = null) =>
22112211
innerException as HttpIOException ?? new IOException(SR.net_http_request_aborted, innerException);

src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ void IHttpStreamHeadersHandler.OnStaticIndexedHeader(int index)
540540
if (index <= LastHPackRequestPseudoHeaderId)
541541
{
542542
if (NetEventSource.Log.IsEnabled()) Trace($"Invalid request pseudo-header ID {index}.");
543-
throw new HttpRequestException(SR.net_http_invalid_response, httpRequestError: HttpRequestError.InvalidResponse);
543+
throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response);
544544
}
545545
else if (index <= LastHPackStatusPseudoHeaderId)
546546
{
@@ -563,7 +563,7 @@ void IHttpStreamHeadersHandler.OnStaticIndexedHeader(int index, ReadOnlySpan<byt
563563
if (index <= LastHPackRequestPseudoHeaderId)
564564
{
565565
if (NetEventSource.Log.IsEnabled()) Trace($"Invalid request pseudo-header ID {index}.");
566-
throw new HttpRequestException(SR.net_http_invalid_response, httpRequestError: HttpRequestError.InvalidResponse);
566+
throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response);
567567
}
568568
else if (index <= LastHPackStatusPseudoHeaderId)
569569
{
@@ -589,7 +589,7 @@ private void AdjustHeaderBudget(int amount)
589589
_headerBudgetRemaining -= amount;
590590
if (_headerBudgetRemaining < 0)
591591
{
592-
throw new HttpRequestException(SR.Format(SR.net_http_response_headers_exceeded_length, _connection._pool.Settings.MaxResponseHeadersByteLength), httpRequestError: HttpRequestError.ConfigurationLimitExceeded);
592+
throw new HttpRequestException(HttpRequestError.ConfigurationLimitExceeded, SR.Format(SR.net_http_response_headers_exceeded_length, _connection._pool.Settings.MaxResponseHeadersByteLength));
593593
}
594594
}
595595

@@ -611,14 +611,14 @@ private void OnStatus(int statusCode)
611611
if (_responseProtocolState == ResponseProtocolState.ExpectingHeaders)
612612
{
613613
if (NetEventSource.Log.IsEnabled()) Trace("Received extra status header.");
614-
throw new HttpRequestException(SR.net_http_invalid_response_multiple_status_codes, httpRequestError: HttpRequestError.ConfigurationLimitExceeded);
614+
throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response_multiple_status_codes);
615615
}
616616

617617
if (_responseProtocolState != ResponseProtocolState.ExpectingStatus)
618618
{
619619
// Pseudo-headers are allowed only in header block
620620
if (NetEventSource.Log.IsEnabled()) Trace($"Status pseudo-header received in {_responseProtocolState} state.");
621-
throw new HttpRequestException(SR.net_http_invalid_response_pseudo_header_in_trailer, httpRequestError: HttpRequestError.InvalidResponse);
621+
throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response_pseudo_header_in_trailer);
622622
}
623623

624624
Debug.Assert(_response != null);
@@ -681,7 +681,7 @@ private void OnHeader(HeaderDescriptor descriptor, ReadOnlySpan<byte> value)
681681
if (_responseProtocolState != ResponseProtocolState.ExpectingHeaders && _responseProtocolState != ResponseProtocolState.ExpectingTrailingHeaders)
682682
{
683683
if (NetEventSource.Log.IsEnabled()) Trace("Received header before status.");
684-
throw new HttpRequestException(SR.net_http_invalid_response, httpRequestError: HttpRequestError.InvalidResponse);
684+
throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response);
685685
}
686686

687687
Encoding? valueEncoding = _connection._pool.Settings._responseHeaderEncodingSelector?.Invoke(descriptor.Name, _request);
@@ -725,7 +725,7 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
725725
else
726726
{
727727
if (NetEventSource.Log.IsEnabled()) Trace($"Invalid response pseudo-header '{Encoding.ASCII.GetString(name)}'.");
728-
throw new HttpRequestException(SR.net_http_invalid_response, httpRequestError: HttpRequestError.InvalidResponse);
728+
throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.net_http_invalid_response);
729729
}
730730
}
731731
else
@@ -734,7 +734,7 @@ public void OnHeader(ReadOnlySpan<byte> name, ReadOnlySpan<byte> value)
734734
if (!HeaderDescriptor.TryGet(name, out HeaderDescriptor descriptor))
735735
{
736736
// Invalid header name
737-
throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name)), httpRequestError: HttpRequestError.InvalidResponse);
737+
throw new HttpRequestException(HttpRequestError.InvalidResponse, SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name)));
738738
}
739739

740740
OnHeader(descriptor, value);

src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, lon
208208

209209
if (quicStream == null)
210210
{
211-
throw new HttpRequestException(SR.net_http_request_aborted, null, RequestRetryType.RetryOnConnectionFailure);
211+
throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_request_aborted, null, RequestRetryType.RetryOnConnectionFailure);
212212
}
213213

214214
requestStream!.StreamId = quicStream.Id;
@@ -221,7 +221,7 @@ public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, lon
221221

222222
if (goAway)
223223
{
224-
throw new HttpRequestException(SR.net_http_request_aborted, null, RequestRetryType.RetryOnConnectionFailure);
224+
throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_request_aborted, null, RequestRetryType.RetryOnConnectionFailure);
225225
}
226226

227227
if (NetEventSource.Log.IsEnabled()) Trace($"Sending request: {request}");
@@ -237,7 +237,7 @@ public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, lon
237237
{
238238
// This will happen if we aborted _connection somewhere and we have pending OpenOutboundStreamAsync call.
239239
// note that _abortException may be null if we closed the connection in response to a GOAWAY frame
240-
throw new HttpRequestException(SR.net_http_client_execution_error, _abortException, RequestRetryType.RetryOnConnectionFailure);
240+
throw new HttpRequestException(HttpRequestError.Unknown, SR.net_http_client_execution_error, _abortException, RequestRetryType.RetryOnConnectionFailure);
241241
}
242242
finally
243243
{

0 commit comments

Comments
 (0)