using CryptoExchange.Net.Objects.Errors;
using System;
namespace CryptoExchange.Net.Objects
{
///
/// Base class for errors
///
public abstract class Error
{
private int? _code;
///
/// The int error code the server returned; or the http status code int value if there was no error code.
///
/// Note:
/// The property should be used for more generic error checking; it might contain a string error code if the server does not return an int code.
///
public int? Code
{
get
{
if (_code.HasValue)
return _code;
return int.TryParse(ErrorCode, out var r) ? r : null;
}
set
{
_code = value;
}
}
///
/// The error code returned by the server
///
public string? ErrorCode { get; set; }
///
/// The error description
///
public string? ErrorDescription { get; set; }
///
/// Error type
///
public ErrorType ErrorType { get; set; }
///
/// Whether the error is transient and can be retried
///
public bool IsTransient { get; set; }
///
/// The server message for the error that occurred
///
public string? Message { get; set; }
///
/// Underlying exception
///
public Exception? Exception { get; set; }
///
/// ctor
///
protected Error(string? errorCode, ErrorInfo errorInfo, Exception? exception)
{
ErrorCode = errorCode;
ErrorType = errorInfo.ErrorType;
Message = errorInfo.Message;
ErrorDescription = errorInfo.ErrorDescription;
IsTransient = errorInfo.IsTransient;
Exception = exception;
}
///
/// String representation
///
///
public override string ToString()
{
return Code != null
? $"[{GetType().Name}.{ErrorType}] {Code}: {GetErrorDescription()}"
: $"[{GetType().Name}.{ErrorType}] {GetErrorDescription()}";
}
private string GetErrorDescription()
{
if (!string.IsNullOrEmpty(Message))
return Message!;
if (ErrorDescription != "Unknown error" || Exception == null)
return ErrorDescription!;
return Exception.Message;
}
}
///
/// Cant reach server error
///
public class CantConnectError : Error
{
///
/// Default error info
///
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.UnableToConnect, false, "Can't connect to the server");
///
/// ctor
///
public CantConnectError() : base(null, _errorInfo, null) { }
///
/// ctor
///
public CantConnectError(Exception? exception) : base(null, _errorInfo, exception) { }
///
/// ctor
///
protected CantConnectError(ErrorInfo info, Exception? exception) : base(null, info, exception) { }
}
///
/// No api credentials provided while trying to access a private endpoint
///
public class NoApiCredentialsError : Error
{
///
/// Default error info
///
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.MissingCredentials, false,
"No credentials provided for private endpoint, set the `ApiCredentials` option in the client configuration");
///
/// ctor
///
public NoApiCredentialsError() : base(null, _errorInfo, null) { }
///
/// ctor
///
protected NoApiCredentialsError(ErrorInfo info, Exception? exception) : base(null, info, exception) { }
}
///
/// Error returned by the server
///
public class ServerError : Error
{
///
/// ctor
///
public ServerError(ErrorType type, string message, Exception? exception = null)
: base(null, new ErrorInfo(type, message), exception)
{
}
///
/// ctor
///
public ServerError(ErrorInfo errorInfo, Exception? exception = null)
: base(null, errorInfo, exception) { }
///
/// ctor
///
public ServerError(int errorCode, ErrorInfo errorInfo, Exception? exception = null)
: this(errorCode.ToString(), errorInfo, exception) { }
///
/// ctor
///
public ServerError(string errorCode, ErrorInfo errorInfo, Exception? exception = null) : base(errorCode, errorInfo, exception) { }
}
///
/// Web error returned by the server
///
public class WebError : Error
{
///
/// Default error info
///
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.NetworkError, true, "Failed to complete the request to the server due to a network error");
///
/// ctor
///
public WebError(string? message = null, Exception? exception = null) : base(null, _errorInfo with { Message = (message?.Length > 0 ? _errorInfo.Message + ": " + message : _errorInfo.Message) }, exception) { }
}
///
/// Timeout error waiting for a response from the server
///
public class TimeoutError : Error
{
///
/// Default error info
///
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.Timeout, false, "Failed to receive a response from the server in time");
///
/// ctor
///
public TimeoutError(string? message = null, Exception? exception = null) : base(null, _errorInfo with { Message = (message?.Length > 0 ? _errorInfo.Message + ": " + message : _errorInfo.Message) }, exception) { }
}
///
/// Error while deserializing data
///
public class DeserializeError : Error
{
///
/// Default error info
///
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.DeserializationFailed, false, "Failed to deserialize data");
///
/// ctor
///
public DeserializeError(string? message = null, Exception? exception = null)
: base(null,
_errorInfo with
{
Message = message?.Length > 0
? message
: _errorInfo.Message
},
exception) { }
}
///
/// An invalid parameter has been provided
///
public class ArgumentError : Error
{
///
/// Default error info for missing parameter
///
protected static readonly ErrorInfo _missingInfo = new ErrorInfo(ErrorType.MissingParameter, false, "Missing parameter");
///
/// Default error info for invalid parameter
///
protected static readonly ErrorInfo _invalidInfo = new ErrorInfo(ErrorType.InvalidParameter, false, "Invalid parameter");
///
/// ctor
///
public static ArgumentError Missing(string parameterName, string? message = null) => new ArgumentError(_missingInfo with { Message = message == null ? $"{_missingInfo.Message} '{parameterName}'" : $"{_missingInfo.Message} '{parameterName}': {message}" }, null);
///
/// ctor
///
public static ArgumentError Invalid(string parameterName, string message) => new ArgumentError(_invalidInfo with { Message = $"{_invalidInfo.Message} '{parameterName}': {message}" }, null);
///
/// ctor
///
protected ArgumentError(ErrorInfo info, Exception? exception) : base(null, info, exception) { }
}
///
/// Rate limit exceeded (client side)
///
public abstract class BaseRateLimitError : Error
{
///
/// When the request can be retried
///
public DateTime? RetryAfter { get; set; }
///
/// ctor
///
protected BaseRateLimitError(ErrorInfo errorInfo, Exception? exception) : base(null, errorInfo, exception) { }
}
///
/// Rate limit exceeded (client side)
///
public class ClientRateLimitError : BaseRateLimitError
{
///
/// Default error info
///
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.RateLimitRequest, false, "Client rate limit exceeded");
///
/// ctor
///
public ClientRateLimitError(string? message = null, Exception? exception = null) : base(_errorInfo with { Message = (message?.Length > 0 ? _errorInfo.Message + ": " + message : _errorInfo.Message) }, exception) { }
///
/// ctor
///
protected ClientRateLimitError(ErrorInfo info, Exception? exception) : base(info, exception) { }
}
///
/// Rate limit exceeded (server side)
///
public class ServerRateLimitError : BaseRateLimitError
{
///
/// Default error info
///
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.RateLimitRequest, false, "Server rate limit exceeded");
///
/// ctor
///
public ServerRateLimitError(string? message = null, Exception? exception = null) : base(_errorInfo with { Message = (message?.Length > 0 ? _errorInfo.Message + ": " + message : _errorInfo.Message) }, exception) { }
///
/// ctor
///
protected ServerRateLimitError(ErrorInfo info, Exception? exception) : base(info, exception) { }
}
///
/// Cancellation requested
///
public class CancellationRequestedError : Error
{
///
/// Default error info
///
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.CancellationRequested, false, "Cancellation requested");
///
/// ctor
///
public CancellationRequestedError(Exception? exception = null) : base(null, _errorInfo, null) { }
///
/// ctor
///
protected CancellationRequestedError(ErrorInfo info, Exception? exception) : base(null, info, exception) { }
}
///
/// Invalid operation requested
///
public class InvalidOperationError : Error
{
///
/// Default error info
///
protected static readonly ErrorInfo _errorInfo = new ErrorInfo(ErrorType.InvalidOperation, false, "Operation invalid");
///
/// ctor
///
public InvalidOperationError(string message) : base(null, _errorInfo with { Message = message }, null) { }
///
/// ctor
///
protected InvalidOperationError(ErrorInfo info, Exception? exception) : base(null, info, exception) { }
}
}