1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-08 16:36:15 +00:00

Cleaned up errors, fix for socket combines

This commit is contained in:
Jkorf 2020-11-19 10:43:11 +01:00
parent f3814e9946
commit e53ca97045
5 changed files with 68 additions and 188 deletions

View File

@ -101,7 +101,7 @@ namespace CryptoExchange.Net
{
var info = "Empty data object received";
log.Write(LogVerbosity.Error, info);
return new CallResult<JToken>(null, new DeserializeError(info));
return new CallResult<JToken>(null, new DeserializeError(info, data));
}
try
@ -110,18 +110,18 @@ namespace CryptoExchange.Net
}
catch (JsonReaderException jre)
{
var info = $"Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}. Data: {data}";
return new CallResult<JToken>(null, new DeserializeError(info));
var info = $"Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}";
return new CallResult<JToken>(null, new DeserializeError(info, data));
}
catch (JsonSerializationException jse)
{
var info = $"Deserialize JsonSerializationException: {jse.Message}. Data: {data}";
return new CallResult<JToken>(null, new DeserializeError(info));
var info = $"Deserialize JsonSerializationException: {jse.Message}";
return new CallResult<JToken>(null, new DeserializeError(info, data));
}
catch (Exception ex)
{
var info = $"Deserialize Unknown Exception: {(ex.InnerException?.Message ?? ex.Message)}. Data: {data}";
return new CallResult<JToken>(null, new DeserializeError(info));
var info = $"Deserialize Unknown Exception: {(ex.InnerException?.Message ?? ex.Message)}";
return new CallResult<JToken>(null, new DeserializeError(info, data));
}
}
@ -186,21 +186,21 @@ namespace CryptoExchange.Net
}
catch (JsonReaderException jre)
{
var info = $"{(requestId != null ? $"[{requestId}] " : "")}Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}. Received data: {obj}";
var info = $"{(requestId != null ? $"[{requestId}] " : "")}Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}";
log.Write(LogVerbosity.Error, info);
return new CallResult<T>(default, new DeserializeError(info));
return new CallResult<T>(default, new DeserializeError(info, obj));
}
catch (JsonSerializationException jse)
{
var info = $"{(requestId != null ? $"[{requestId}] " : "")}Deserialize JsonSerializationException: {jse.Message}. Received data: {obj}";
var info = $"{(requestId != null ? $"[{requestId}] " : "")}Deserialize JsonSerializationException: {jse.Message}";
log.Write(LogVerbosity.Error, info);
return new CallResult<T>(default, new DeserializeError(info));
return new CallResult<T>(default, new DeserializeError(info, obj));
}
catch (Exception ex)
{
var info = $"{(requestId != null ? $"[{requestId}] " : "")}Deserialize Unknown Exception: {(ex.InnerException?.Message ?? ex.Message)}. Received data: {obj}";
var info = $"{(requestId != null ? $"[{requestId}] " : "")}Deserialize Unknown Exception: {(ex.InnerException?.Message ?? ex.Message)}";
log.Write(LogVerbosity.Error, info);
return new CallResult<T>(default, new DeserializeError(info));
return new CallResult<T>(default, new DeserializeError(info, obj));
}
}
@ -211,7 +211,7 @@ namespace CryptoExchange.Net
/// <param name="stream">The stream to deserialize</param>
/// <param name="serializer">A specific serializer to use</param>
/// <param name="requestId">Id of the request</param>
/// <param name="elapsedMilliseconds">Milliseconds reponse time</param>
/// <param name="elapsedMilliseconds">Milliseconds response time</param>
/// <returns></returns>
protected async Task<CallResult<T>> Deserialize<T>(Stream stream, JsonSerializer? serializer = null, int? requestId = null, long? elapsedMilliseconds = null)
{
@ -237,7 +237,7 @@ namespace CryptoExchange.Net
stream.Seek(0, SeekOrigin.Begin);
var data = await ReadStream(stream).ConfigureAwait(false);
log.Write(LogVerbosity.Error, $"{(requestId != null ? $"[{requestId}] " : "")}Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}, data: {data}");
return new CallResult<T>(default, new DeserializeError(data));
return new CallResult<T>(default, new DeserializeError($"Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}", data));
}
catch (JsonSerializationException jse)
{
@ -245,7 +245,7 @@ namespace CryptoExchange.Net
stream.Seek(0, SeekOrigin.Begin);
var data = await ReadStream(stream).ConfigureAwait(false);
log.Write(LogVerbosity.Error, $"{(requestId != null ? $"[{requestId}] " : "")}Deserialize JsonSerializationException: {jse.Message}, data: {data}");
return new CallResult<T>(default, new DeserializeError(data));
return new CallResult<T>(default, new DeserializeError($"Deserialize JsonSerializationException: {jse.Message}", data));
}
catch (Exception ex)
{
@ -253,7 +253,7 @@ namespace CryptoExchange.Net
stream.Seek(0, SeekOrigin.Begin);
var data = await ReadStream(stream).ConfigureAwait(false);
log.Write(LogVerbosity.Error, $"{(requestId != null ? $"[{requestId}] " : "")}Deserialize Unknown Exception: {(ex.InnerException?.Message ?? ex.Message)}, data: {data}");
return new CallResult<T>(default, new DeserializeError(data));
return new CallResult<T>(default, new DeserializeError($"Deserialize Unknown Exception: {(ex.InnerException?.Message ?? ex.Message)}", data));
}
}

View File

@ -294,7 +294,7 @@
<param name="stream">The stream to deserialize</param>
<param name="serializer">A specific serializer to use</param>
<param name="requestId">Id of the request</param>
<param name="elapsedMilliseconds">Milliseconds reponse time</param>
<param name="elapsedMilliseconds">Milliseconds response time</param>
<returns></returns>
</member>
<member name="M:CryptoExchange.Net.BaseClient.NextId">
@ -1465,20 +1465,20 @@
</member>
<member name="P:CryptoExchange.Net.Objects.Error.Code">
<summary>
The error code
The error code from the server
</summary>
</member>
<member name="P:CryptoExchange.Net.Objects.Error.Message">
<summary>
The message for the error that occured
The message for the error that occurred
</summary>
</member>
<member name="P:CryptoExchange.Net.Objects.Error.Data">
<summary>
Optional data for the error
The data which caused the error
</summary>
</member>
<member name="M:CryptoExchange.Net.Objects.Error.#ctor(System.Int32,System.String,System.Object)">
<member name="M:CryptoExchange.Net.Objects.Error.#ctor(System.Nullable{System.Int32},System.String,System.Object)">
<summary>
ctor
</summary>
@ -1537,10 +1537,19 @@
Web error returned by the server
</summary>
</member>
<member name="M:CryptoExchange.Net.Objects.WebError.#ctor(System.Object)">
<member name="M:CryptoExchange.Net.Objects.WebError.#ctor(System.String,System.Object)">
<summary>
ctor
</summary>
<param name="message"></param>
<param name="data"></param>
</member>
<member name="M:CryptoExchange.Net.Objects.WebError.#ctor(System.Int32,System.String,System.Object)">
<summary>
ctor
</summary>
<param name="code"></param>
<param name="message"></param>
<param name="data"></param>
</member>
<member name="T:CryptoExchange.Net.Objects.DeserializeError">
@ -1548,18 +1557,19 @@
Error while deserializing data
</summary>
</member>
<member name="M:CryptoExchange.Net.Objects.DeserializeError.#ctor(System.Object)">
<member name="M:CryptoExchange.Net.Objects.DeserializeError.#ctor(System.String,System.Object)">
<summary>
ctor
</summary>
<param name="data">Deserializing data</param>
<param name="message">The error message</param>
<param name="data">The data which caused the error</param>
</member>
<member name="T:CryptoExchange.Net.Objects.UnknownError">
<summary>
Unknown error
</summary>
</member>
<member name="M:CryptoExchange.Net.Objects.UnknownError.#ctor(System.Object)">
<member name="M:CryptoExchange.Net.Objects.UnknownError.#ctor(System.String,System.Object)">
<summary>
ctor
</summary>
@ -3050,148 +3060,5 @@
<member name="M:CryptoExchange.Net.Sockets.WebsocketFactory.CreateWebsocket(CryptoExchange.Net.Logging.Log,System.String,System.Collections.Generic.IDictionary{System.String,System.String},System.Collections.Generic.IDictionary{System.String,System.String})">
<inheritdoc />
</member>
<member name="T:System.Diagnostics.CodeAnalysis.AllowNullAttribute">
<summary>
Specifies that <see langword="null"/> is allowed as an input even if the
corresponding type disallows it.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.AllowNullAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.AllowNullAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.DisallowNullAttribute">
<summary>
Specifies that <see langword="null"/> is disallowed as an input even if the
corresponding type allows it.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.DisallowNullAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DisallowNullAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute">
<summary>
Specifies that a method that will never return under any circumstance.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute">
<summary>
Specifies that the method will not return if the associated <see cref="T:System.Boolean"/>
parameter is passed the specified value.
</summary>
</member>
<member name="P:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute.ParameterValue">
<summary>
Gets the condition parameter value.
Code after the method is considered unreachable by diagnostics if the argument
to the associated parameter matches this value.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute.#ctor(System.Boolean)">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute"/>
class with the specified parameter value.
</summary>
<param name="parameterValue">
The condition parameter value.
Code after the method is considered unreachable by diagnostics if the argument
to the associated parameter matches this value.
</param>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.MaybeNullAttribute">
<summary>
Specifies that an output may be <see langword="null"/> even if the
corresponding type disallows it.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.MaybeNullAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.MaybeNullAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute">
<summary>
Specifies that when a method returns <see cref="P:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.ReturnValue"/>,
the parameter may be <see langword="null"/> even if the corresponding type disallows it.
</summary>
</member>
<member name="P:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.ReturnValue">
<summary>
Gets the return value condition.
If the method returns this value, the associated parameter may be <see langword="null"/>.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute.#ctor(System.Boolean)">
<summary>
Initializes the attribute with the specified return value condition.
</summary>
<param name="returnValue">
The return value condition.
If the method returns this value, the associated parameter may be <see langword="null"/>.
</param>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.NotNullAttribute">
<summary>
Specifies that an output is not <see langword="null"/> even if the
corresponding type allows it.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.NotNullAttribute.#ctor">
<summary>
Initializes a new instance of the <see cref="T:System.Diagnostics.CodeAnalysis.NotNullAttribute"/> class.
</summary>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute">
<summary>
Specifies that the output will be non-<see langword="null"/> if the
named parameter is non-<see langword="null"/>.
</summary>
</member>
<member name="P:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute.ParameterName">
<summary>
Gets the associated parameter name.
The output will be non-<see langword="null"/> if the argument to the
parameter specified is non-<see langword="null"/>.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute.#ctor(System.String)">
<summary>
Initializes the attribute with the associated parameter name.
</summary>
<param name="parameterName">
The associated parameter name.
The output will be non-<see langword="null"/> if the argument to the
parameter specified is non-<see langword="null"/>.
</param>
</member>
<member name="T:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute">
<summary>
Specifies that when a method returns <see cref="P:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.ReturnValue"/>,
the parameter will not be <see langword="null"/> even if the corresponding type allows it.
</summary>
</member>
<member name="P:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.ReturnValue">
<summary>
Gets the return value condition.
If the method returns this value, the associated parameter will not be <see langword="null"/>.
</summary>
</member>
<member name="M:System.Diagnostics.CodeAnalysis.NotNullWhenAttribute.#ctor(System.Boolean)">
<summary>
Initializes the attribute with the specified return value condition.
</summary>
<param name="returnValue">
The return value condition.
If the method returns this value, the associated parameter will not be <see langword="null"/>.
</param>
</member>
</members>
</doc>

View File

@ -6,16 +6,17 @@
public abstract class Error
{
/// <summary>
/// The error code
/// The error code from the server
/// </summary>
public int Code { get; set; }
public int? Code { get; set; }
/// <summary>
/// The message for the error that occured
/// The message for the error that occurred
/// </summary>
public string Message { get; set; }
/// <summary>
/// Optional data for the error
/// The data which caused the error
/// </summary>
public object? Data { get; set; }
@ -25,7 +26,7 @@
/// <param name="code"></param>
/// <param name="message"></param>
/// <param name="data"></param>
protected Error(int code, string message, object? data)
protected Error(int? code, string message, object? data)
{
Code = code;
Message = message;
@ -50,7 +51,7 @@
/// <summary>
/// ctor
/// </summary>
public CantConnectError() : base(1, "Can't connect to the server", null) { }
public CantConnectError() : base(null, "Can't connect to the server", null) { }
}
/// <summary>
@ -61,7 +62,7 @@
/// <summary>
/// ctor
/// </summary>
public NoApiCredentialsError() : base(2, "No credentials provided for private endpoint", null) { }
public NoApiCredentialsError() : base(null, "No credentials provided for private endpoint", null) { }
}
/// <summary>
@ -74,7 +75,7 @@
/// </summary>
/// <param name="message"></param>
/// <param name="data"></param>
public ServerError(string message, object? data = null) : base(3, "Server error: " + message, data) { }
public ServerError(string message, object? data = null) : base(null, message, data) { }
/// <summary>
/// ctor
@ -95,8 +96,17 @@
/// <summary>
/// ctor
/// </summary>
/// <param name="message"></param>
/// <param name="data"></param>
public WebError(object? data) : base(4, "Web error", data) { }
public WebError(string message, object? data = null) : base(null, message, data) { }
/// <summary>
/// ctor
/// </summary>
/// <param name="code"></param>
/// <param name="message"></param>
/// <param name="data"></param>
public WebError(int code, string message, object? data = null) : base(code, message, data) { }
}
/// <summary>
@ -107,8 +117,9 @@
/// <summary>
/// ctor
/// </summary>
/// <param name="data">Deserializing data</param>
public DeserializeError(object? data) : base(5, "Error deserializing data", data) { }
/// <param name="message">The error message</param>
/// <param name="data">The data which caused the error</param>
public DeserializeError(string message, object? data) : base(null, message, data) { }
}
/// <summary>
@ -120,7 +131,7 @@
/// ctor
/// </summary>
/// <param name="data">Error data</param>
public UnknownError(object? data = null) : base(6, "Unknown error occured", data) { }
public UnknownError(string message, object? data = null) : base(null, message, data) { }
}
/// <summary>
@ -132,7 +143,7 @@
/// ctor
/// </summary>
/// <param name="message"></param>
public ArgumentError(string message) : base(7, "Invalid parameter: " + message, null) { }
public ArgumentError(string message) : base(null, "Invalid parameter: " + message, null) { }
}
/// <summary>
@ -144,7 +155,7 @@
/// ctor
/// </summary>
/// <param name="message"></param>
public RateLimitError(string message) : base(8, "Rate limit exceeded: " + message, null) { }
public RateLimitError(string message) : base(null, "Rate limit exceeded: " + message, null) { }
}
/// <summary>
@ -155,6 +166,6 @@
/// <summary>
/// ctor
/// </summary>
public CancellationRequestedError() : base(9, "Cancellation requested", null) { }
public CancellationRequestedError() : base(null, "Cancellation requested", null) { }
}
}

View File

@ -232,7 +232,7 @@ namespace CryptoExchange.Net
var parseResult = ValidateJson(data);
if (!parseResult.Success)
return WebCallResult<T>.CreateErrorResult(response.StatusCode, response.ResponseHeaders, new ServerError(data));
return WebCallResult<T>.CreateErrorResult(response.StatusCode, response.ResponseHeaders, parseResult.Error!);
var error = await TryParseError(parseResult.Data);
if (error != null)
return WebCallResult<T>.CreateErrorResult(response.StatusCode, response.ResponseHeaders, error);
@ -257,7 +257,9 @@ namespace CryptoExchange.Net
responseStream.Close();
response.Close();
var parseResult = ValidateJson(data);
return new WebCallResult<T>(statusCode, headers, default, parseResult.Success ? ParseErrorResponse(parseResult.Data) : new ServerError(data));
var error = parseResult.Success ? ParseErrorResponse(parseResult.Data) : parseResult.Error!;
error.Code = (int)response.StatusCode;
return new WebCallResult<T>(statusCode, headers, default, error);
}
}
catch (HttpRequestException requestException)

View File

@ -294,7 +294,7 @@ namespace CryptoExchange.Net
var connectResult = await ConnectSocket(socket).ConfigureAwait(false);
if (!connectResult)
return new CallResult<bool>(false, new CantConnectError());
return new CallResult<bool>(false, connectResult.Error);
if (!authenticated || socket.Authenticated)
return new CallResult<bool>(true, null);
@ -427,7 +427,7 @@ namespace CryptoExchange.Net
/// <returns></returns>
protected virtual SocketConnection GetWebsocket(string address, bool authenticated)
{
var socketResult = sockets.Where(s => s.Value.Socket.Url == address.TrimEnd('/')
var socketResult = sockets.Where(s => s.Value.Socket.Url.TrimEnd('/') == address.TrimEnd('/')
&& (s.Value.Authenticated == authenticated || !authenticated) && s.Value.Connected).OrderBy(s => s.Value.HandlerCount).FirstOrDefault();
var result = socketResult.Equals(default(KeyValuePair<int, SocketConnection>)) ? null : socketResult.Value;
if (result != null)