mirror of
https://github.com/GoodOlClint/PSProxmoxVE.git
synced 2026-08-25 03:46:49 +00:00
fix: surface HttpClient timeouts as PveApiException(RequestTimeout)
When HttpClient.Timeout elapses, .NET throws TaskCanceledException — not HttpRequestException — so the existing catch in PveHttpClient.SendAsync missed it and callers got a raw stack trace. With -TimeoutSeconds now configurable and documented, this gap became user-visible. In .NET 5+ HttpClient surfaces transport timeouts as TaskCanceledException with a TimeoutException inner; user-driven token cancellation does not. Catch by that inner-type signature and rethrow as PveApiException with HttpStatusCode.RequestTimeout, the resource path, and a message that reports the configured timeout. Adds SendAsync_TimeoutFires_ThrowsPveApiExceptionWithRequestTimeout which swaps in a delaying HttpMessageHandler with a 50ms timeout to exercise the path deterministically. Drops the redundant DefaultSessionTimeoutIs100Seconds test (covered by PveSessionTests.Timeout_DefaultIs100Seconds and the existing flow-through test). Addresses PR #61 review feedback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -353,6 +353,17 @@ namespace PSProxmoxVE.Core.Client
|
||||
{
|
||||
response = await _httpClient.SendAsync(request).ConfigureAwait(false);
|
||||
}
|
||||
catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
|
||||
{
|
||||
// HttpClient.Timeout elapsed. In .NET 5+, HttpClient surfaces transport
|
||||
// timeouts as TaskCanceledException with a TimeoutException inner —
|
||||
// distinguishing them from caller-driven CancellationToken cancellation.
|
||||
var seconds = _httpClient.Timeout == System.Threading.Timeout.InfiniteTimeSpan
|
||||
? "infinite"
|
||||
: _httpClient.Timeout.TotalSeconds.ToString("0", System.Globalization.CultureInfo.InvariantCulture) + "s";
|
||||
throw new PveApiException(HttpStatusCode.RequestTimeout,
|
||||
$"Request timed out after {seconds}.", resource, httpMethod, ex);
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
throw new PveApiException(HttpStatusCode.ServiceUnavailable,
|
||||
|
||||
Reference in New Issue
Block a user