src/Microsoft.Azure.Relay/WebSocketExceptionHelper.cs (90 lines of code) (raw):

// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace Microsoft.Azure.Relay { using System; using System.IO; using System.Net; using System.Net.Http; using System.Net.Sockets; using System.Net.WebSockets; static class WebSocketExceptionHelper { public static bool IsRelayContract(Exception exception) { return Fx.IsFatal(exception) || exception is RelayException || exception is TimeoutException; } public static Exception ConvertToRelayContract(Exception exception, TrackingContext trackingContext, HttpResponseMessage httpResponseMessage = null, bool isListener = true) { string message = exception.Message; if (IsRelayContract(exception)) { return exception; } else if (exception is WebSocketException) { WebException innerWebException; IOException innerIOException; SocketException socketException; if ((innerWebException = exception.InnerException as WebException) != null) { HttpWebResponse httpWebResponse; if ((httpWebResponse = innerWebException.Response as HttpWebResponse) != null) { return CreateExceptionForStatus(httpWebResponse.StatusCode, httpWebResponse.StatusDescription, exception, trackingContext, isListener); } else if (innerWebException.Status == WebExceptionStatus.NameResolutionFailure) { message = innerWebException.Message; } } else if ((innerIOException = exception.InnerException as IOException) != null) { message = innerIOException.Message; } else if ((socketException = exception.InnerException as SocketException) != null) { if (socketException.SocketErrorCode == SocketError.HostNotFound) { message = socketException.Message; } } else if (httpResponseMessage != null || (httpResponseMessage = (HttpResponseMessage)exception.Data[typeof(HttpResponseMessage).FullName]) != null) { return CreateExceptionForStatus(httpResponseMessage.StatusCode, httpResponseMessage.ReasonPhrase, exception, trackingContext, isListener); } } if (trackingContext != null) { message = trackingContext.EnsureTrackableMessage(message); } return new RelayException(message, exception); } static Exception CreateExceptionForStatus(HttpStatusCode statusCode, string statusDescription, Exception inner, TrackingContext trackingContext, bool isListener) { if (trackingContext != null) { statusDescription = trackingContext.EnsureTrackableMessage(statusDescription); } switch (statusCode) { case HttpStatusCode.Unauthorized: return new AuthorizationFailedException(statusDescription, inner); case HttpStatusCode.NotFound: return new EndpointNotFoundException(statusDescription, inner, isTransient: !isListener); case HttpStatusCode.GatewayTimeout: case HttpStatusCode.RequestTimeout: return new TimeoutException(statusCode + ": " + statusDescription, inner); case HttpStatusCode.BadRequest: case HttpStatusCode.InternalServerError: case HttpStatusCode.NotImplemented: case HttpStatusCode.BadGateway: case HttpStatusCode.ServiceUnavailable: default: return new RelayException(statusCode + ": " + statusDescription, inner); } } } }