Handle WebSocket exceptions (#155)

This commit is contained in:
Frederik Carlier
2018-05-01 00:16:06 +02:00
committed by Brendan Burns
parent a5a15d7042
commit c60882088a

View File

@@ -1,8 +1,11 @@
using k8s.Models;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Rest;
using Microsoft.Rest.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.WebSockets;
using System.Security.Cryptography.X509Certificates;
@@ -270,6 +273,46 @@ namespace k8s
{
webSocket = await webSocketBuilder.BuildAndConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);
}
catch (WebSocketException wse) when (wse.WebSocketErrorCode == WebSocketError.HeaderError || (wse.InnerException is WebSocketException && ((WebSocketException)wse.InnerException).WebSocketErrorCode == WebSocketError.HeaderError))
{
// This usually indicates the server sent an error message, like 400 Bad Request. Unfortunately, the WebSocket client
// class doesn't give us a lot of information about what went wrong. So, retry the connection.
var uriBuilder = new UriBuilder(uri);
uriBuilder.Scheme = uri.Scheme == "wss" ? "https" : "http";
var response = await this.HttpClient.GetAsync(uriBuilder.Uri, cancellationToken).ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.SwitchingProtocols)
{
// This should never happen - the server just allowed us to switch to WebSockets but the previous call didn't work.
// Rethrow the original exception
response.Dispose();
throw;
}
else
{
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
// Try to parse the content as a V1Status object
var genericObject = SafeJsonConvert.DeserializeObject<KubernetesObject>(content);
V1Status status = null;
if (genericObject.ApiVersion == "v1" && genericObject.Kind == "Status")
{
status = SafeJsonConvert.DeserializeObject<V1Status>(content);
}
var ex = new HttpOperationException($"The operation returned an invalid status code: {response.StatusCode}", wse)
{
Response = new HttpResponseMessageWrapper(response, content),
Body = status != null ? (object)status : content,
};
response.Dispose();
throw ex;
}
}
catch (Exception ex)
{
if (_shouldTrace)