diff --git a/CryptoExchange.Net/BaseClient.cs b/CryptoExchange.Net/BaseClient.cs index 166aa83..43b9a96 100644 --- a/CryptoExchange.Net/BaseClient.cs +++ b/CryptoExchange.Net/BaseClient.cs @@ -101,7 +101,7 @@ namespace CryptoExchange.Net { var info = "Empty data object received"; log.Write(LogVerbosity.Error, info); - return new CallResult(null, new DeserializeError(info)); + return new CallResult(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(null, new DeserializeError(info)); + var info = $"Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}"; + return new CallResult(null, new DeserializeError(info, data)); } catch (JsonSerializationException jse) { - var info = $"Deserialize JsonSerializationException: {jse.Message}. Data: {data}"; - return new CallResult(null, new DeserializeError(info)); + var info = $"Deserialize JsonSerializationException: {jse.Message}"; + return new CallResult(null, new DeserializeError(info, data)); } catch (Exception ex) { - var info = $"Deserialize Unknown Exception: {(ex.InnerException?.Message ?? ex.Message)}. Data: {data}"; - return new CallResult(null, new DeserializeError(info)); + var info = $"Deserialize Unknown Exception: {(ex.InnerException?.Message ?? ex.Message)}"; + return new CallResult(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(default, new DeserializeError(info)); + return new CallResult(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(default, new DeserializeError(info)); + return new CallResult(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(default, new DeserializeError(info)); + return new CallResult(default, new DeserializeError(info, obj)); } } @@ -211,7 +211,7 @@ namespace CryptoExchange.Net /// The stream to deserialize /// A specific serializer to use /// Id of the request - /// Milliseconds reponse time + /// Milliseconds response time /// protected async Task> Deserialize(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(default, new DeserializeError(data)); + return new CallResult(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(default, new DeserializeError(data)); + return new CallResult(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(default, new DeserializeError(data)); + return new CallResult(default, new DeserializeError($"Deserialize Unknown Exception: {(ex.InnerException?.Message ?? ex.Message)}", data)); } } diff --git a/CryptoExchange.Net/CryptoExchange.Net.xml b/CryptoExchange.Net/CryptoExchange.Net.xml index ab5dbad..2a08992 100644 --- a/CryptoExchange.Net/CryptoExchange.Net.xml +++ b/CryptoExchange.Net/CryptoExchange.Net.xml @@ -294,7 +294,7 @@ The stream to deserialize A specific serializer to use Id of the request - Milliseconds reponse time + Milliseconds response time @@ -1465,20 +1465,20 @@ - The error code + The error code from the server - The message for the error that occured + The message for the error that occurred - Optional data for the error + The data which caused the error - + ctor @@ -1537,10 +1537,19 @@ Web error returned by the server - + ctor + + + + + + ctor + + + @@ -1548,18 +1557,19 @@ Error while deserializing data - + ctor - Deserializing data + The error message + The data which caused the error Unknown error - + ctor @@ -3050,148 +3060,5 @@ - - - Specifies that is allowed as an input even if the - corresponding type disallows it. - - - - - Initializes a new instance of the class. - - - - - Specifies that is disallowed as an input even if the - corresponding type allows it. - - - - - Initializes a new instance of the class. - - - - - Specifies that a method that will never return under any circumstance. - - - - - Initializes a new instance of the class. - - - - - Specifies that the method will not return if the associated - parameter is passed the specified value. - - - - - Gets the condition parameter value. - Code after the method is considered unreachable by diagnostics if the argument - to the associated parameter matches this value. - - - - - Initializes a new instance of the - class with the specified parameter value. - - - The condition parameter value. - Code after the method is considered unreachable by diagnostics if the argument - to the associated parameter matches this value. - - - - - Specifies that an output may be even if the - corresponding type disallows it. - - - - - Initializes a new instance of the class. - - - - - Specifies that when a method returns , - the parameter may be even if the corresponding type disallows it. - - - - - Gets the return value condition. - If the method returns this value, the associated parameter may be . - - - - - Initializes the attribute with the specified return value condition. - - - The return value condition. - If the method returns this value, the associated parameter may be . - - - - - Specifies that an output is not even if the - corresponding type allows it. - - - - - Initializes a new instance of the class. - - - - - Specifies that the output will be non- if the - named parameter is non-. - - - - - Gets the associated parameter name. - The output will be non- if the argument to the - parameter specified is non-. - - - - - Initializes the attribute with the associated parameter name. - - - The associated parameter name. - The output will be non- if the argument to the - parameter specified is non-. - - - - - Specifies that when a method returns , - the parameter will not be even if the corresponding type allows it. - - - - - Gets the return value condition. - If the method returns this value, the associated parameter will not be . - - - - - Initializes the attribute with the specified return value condition. - - - The return value condition. - If the method returns this value, the associated parameter will not be . - - diff --git a/CryptoExchange.Net/Objects/Error.cs b/CryptoExchange.Net/Objects/Error.cs index 0a4b838..7d37369 100644 --- a/CryptoExchange.Net/Objects/Error.cs +++ b/CryptoExchange.Net/Objects/Error.cs @@ -6,16 +6,17 @@ public abstract class Error { /// - /// The error code + /// The error code from the server /// - public int Code { get; set; } + public int? Code { get; set; } + /// - /// The message for the error that occured + /// The message for the error that occurred /// public string Message { get; set; } /// - /// Optional data for the error + /// The data which caused the error /// public object? Data { get; set; } @@ -25,7 +26,7 @@ /// /// /// - protected Error(int code, string message, object? data) + protected Error(int? code, string message, object? data) { Code = code; Message = message; @@ -50,7 +51,7 @@ /// /// ctor /// - public CantConnectError() : base(1, "Can't connect to the server", null) { } + public CantConnectError() : base(null, "Can't connect to the server", null) { } } /// @@ -61,7 +62,7 @@ /// /// ctor /// - public NoApiCredentialsError() : base(2, "No credentials provided for private endpoint", null) { } + public NoApiCredentialsError() : base(null, "No credentials provided for private endpoint", null) { } } /// @@ -74,7 +75,7 @@ /// /// /// - public ServerError(string message, object? data = null) : base(3, "Server error: " + message, data) { } + public ServerError(string message, object? data = null) : base(null, message, data) { } /// /// ctor @@ -95,8 +96,17 @@ /// /// ctor /// + /// /// - public WebError(object? data) : base(4, "Web error", data) { } + public WebError(string message, object? data = null) : base(null, message, data) { } + + /// + /// ctor + /// + /// + /// + /// + public WebError(int code, string message, object? data = null) : base(code, message, data) { } } /// @@ -107,8 +117,9 @@ /// /// ctor /// - /// Deserializing data - public DeserializeError(object? data) : base(5, "Error deserializing data", data) { } + /// The error message + /// The data which caused the error + public DeserializeError(string message, object? data) : base(null, message, data) { } } /// @@ -120,7 +131,7 @@ /// ctor /// /// Error data - public UnknownError(object? data = null) : base(6, "Unknown error occured", data) { } + public UnknownError(string message, object? data = null) : base(null, message, data) { } } /// @@ -132,7 +143,7 @@ /// ctor /// /// - public ArgumentError(string message) : base(7, "Invalid parameter: " + message, null) { } + public ArgumentError(string message) : base(null, "Invalid parameter: " + message, null) { } } /// @@ -144,7 +155,7 @@ /// ctor /// /// - public RateLimitError(string message) : base(8, "Rate limit exceeded: " + message, null) { } + public RateLimitError(string message) : base(null, "Rate limit exceeded: " + message, null) { } } /// @@ -155,6 +166,6 @@ /// /// ctor /// - public CancellationRequestedError() : base(9, "Cancellation requested", null) { } + public CancellationRequestedError() : base(null, "Cancellation requested", null) { } } } diff --git a/CryptoExchange.Net/RestClient.cs b/CryptoExchange.Net/RestClient.cs index 5f5726c..8711d64 100644 --- a/CryptoExchange.Net/RestClient.cs +++ b/CryptoExchange.Net/RestClient.cs @@ -232,7 +232,7 @@ namespace CryptoExchange.Net var parseResult = ValidateJson(data); if (!parseResult.Success) - return WebCallResult.CreateErrorResult(response.StatusCode, response.ResponseHeaders, new ServerError(data)); + return WebCallResult.CreateErrorResult(response.StatusCode, response.ResponseHeaders, parseResult.Error!); var error = await TryParseError(parseResult.Data); if (error != null) return WebCallResult.CreateErrorResult(response.StatusCode, response.ResponseHeaders, error); @@ -257,7 +257,9 @@ namespace CryptoExchange.Net responseStream.Close(); response.Close(); var parseResult = ValidateJson(data); - return new WebCallResult(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(statusCode, headers, default, error); } } catch (HttpRequestException requestException) diff --git a/CryptoExchange.Net/SocketClient.cs b/CryptoExchange.Net/SocketClient.cs index 5632b94..8475263 100644 --- a/CryptoExchange.Net/SocketClient.cs +++ b/CryptoExchange.Net/SocketClient.cs @@ -294,7 +294,7 @@ namespace CryptoExchange.Net var connectResult = await ConnectSocket(socket).ConfigureAwait(false); if (!connectResult) - return new CallResult(false, new CantConnectError()); + return new CallResult(false, connectResult.Error); if (!authenticated || socket.Authenticated) return new CallResult(true, null); @@ -427,7 +427,7 @@ namespace CryptoExchange.Net /// 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)) ? null : socketResult.Value; if (result != null)