|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
namespace System.Net.WebSockets
{
[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public sealed class WebSocketException : Win32Exception
{
private readonly WebSocketError _webSocketErrorCode;
public WebSocketException()
: this(Marshal.GetLastPInvokeError())
{
}
public WebSocketException(WebSocketError error)
: this(error, GetErrorMessage(error))
{
}
public WebSocketException(WebSocketError error, string? message) : base(message ?? SR.net_WebSockets_Generic)
{
_webSocketErrorCode = error;
}
public WebSocketException(WebSocketError error, Exception? innerException)
: this(error, GetErrorMessage(error), innerException)
{
}
public WebSocketException(WebSocketError error, string? message, Exception? innerException)
: base(message ?? SR.net_WebSockets_Generic, innerException)
{
_webSocketErrorCode = error;
}
public WebSocketException(int nativeError)
: base(nativeError)
{
_webSocketErrorCode = !Succeeded(nativeError) ? WebSocketError.NativeError : WebSocketError.Success;
SetErrorCodeOnError(nativeError);
}
public WebSocketException(int nativeError, string? message)
: base(nativeError, message)
{
_webSocketErrorCode = !Succeeded(nativeError) ? WebSocketError.NativeError : WebSocketError.Success;
SetErrorCodeOnError(nativeError);
}
public WebSocketException(int nativeError, Exception? innerException)
: base(SR.net_WebSockets_Generic, innerException)
{
_webSocketErrorCode = !Succeeded(nativeError) ? WebSocketError.NativeError : WebSocketError.Success;
SetErrorCodeOnError(nativeError);
}
public WebSocketException(WebSocketError error, int nativeError)
: this(error, nativeError, GetErrorMessage(error))
{
}
public WebSocketException(WebSocketError error, int nativeError, string? message)
: base(message ?? SR.net_WebSockets_Generic)
{
_webSocketErrorCode = error;
SetErrorCodeOnError(nativeError);
}
public WebSocketException(WebSocketError error, int nativeError, Exception? innerException)
: this(error, nativeError, GetErrorMessage(error), innerException)
{
}
public WebSocketException(WebSocketError error, int nativeError, string? message, Exception? innerException)
: base(message ?? SR.net_WebSockets_Generic, innerException)
{
_webSocketErrorCode = error;
SetErrorCodeOnError(nativeError);
}
public WebSocketException(string? message)
: base(message ?? SR.net_WebSockets_Generic)
{
}
public WebSocketException(string? message, Exception? innerException)
: base(message ?? SR.net_WebSockets_Generic, innerException)
{
}
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[EditorBrowsable(EditorBrowsableState.Never)]
private WebSocketException(SerializationInfo serializationInfo, StreamingContext streamingContext)
: base(serializationInfo, streamingContext)
{
}
[Obsolete(Obsoletions.LegacyFormatterImplMessage, DiagnosticId = Obsoletions.LegacyFormatterImplDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue(nameof(WebSocketErrorCode), _webSocketErrorCode);
}
public override int ErrorCode
{
get
{
return base.NativeErrorCode;
}
}
public WebSocketError WebSocketErrorCode
{
get
{
return _webSocketErrorCode;
}
}
private static string GetErrorMessage(WebSocketError error) =>
// Provide a canned message for the error type.
error switch
{
WebSocketError.InvalidMessageType => SR.Format(SR.net_WebSockets_InvalidMessageType_Generic,
$"{nameof(WebSocket)}.{nameof(WebSocket.CloseAsync)}",
$"{nameof(WebSocket)}.{nameof(WebSocket.CloseOutputAsync)}"),
WebSocketError.Faulted => SR.net_Websockets_WebSocketBaseFaulted,
WebSocketError.NotAWebSocket => SR.net_WebSockets_NotAWebSocket_Generic,
WebSocketError.UnsupportedVersion => SR.net_WebSockets_UnsupportedWebSocketVersion_Generic,
WebSocketError.UnsupportedProtocol => SR.net_WebSockets_UnsupportedProtocol_Generic,
WebSocketError.HeaderError => SR.net_WebSockets_HeaderError_Generic,
WebSocketError.ConnectionClosedPrematurely => SR.net_WebSockets_ConnectionClosedPrematurely_Generic,
WebSocketError.InvalidState => SR.net_WebSockets_InvalidState_Generic,
_ => SR.net_WebSockets_Generic,
};
// Set the error code only if there is an error (i.e. nativeError >= 0). Otherwise the code fails during deserialization
// as the Exception..ctor() throws on setting HResult to 0. The default for HResult is -2147467259.
private void SetErrorCodeOnError(int nativeError)
{
if (!Succeeded(nativeError))
{
HResult = nativeError;
}
}
private static bool Succeeded(int hr)
{
return (hr >= 0);
}
}
}
|