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

Changed web request results to WebCallResult to support response status code

This commit is contained in:
Jan Korf 2019-02-27 10:59:31 +01:00
parent 16b5685606
commit 094369e255
6 changed files with 51 additions and 18 deletions

View File

@ -69,6 +69,13 @@ namespace CryptoExchange.Net
/// <returns></returns> /// <returns></returns>
protected CallResult<JToken> ValidateJson(string data) protected CallResult<JToken> ValidateJson(string data)
{ {
if (string.IsNullOrEmpty(data))
{
var info = "Empty data object received";
log.Write(LogVerbosity.Error, info);
return new CallResult<JToken>(null, new DeserializeError(info));
}
try try
{ {
return new CallResult<JToken>(JToken.Parse(data), null); return new CallResult<JToken>(JToken.Parse(data), null);

View File

@ -1,9 +1,11 @@
using System.IO; using System.IO;
using System.Net;
namespace CryptoExchange.Net.Interfaces namespace CryptoExchange.Net.Interfaces
{ {
public interface IResponse public interface IResponse
{ {
HttpStatusCode StatusCode { get; }
Stream GetResponseStream(); Stream GetResponseStream();
void Close(); void Close();
} }

View File

@ -1,4 +1,6 @@
namespace CryptoExchange.Net.Objects using System.Net;
namespace CryptoExchange.Net.Objects
{ {
public class CallResult<T> public class CallResult<T>
{ {
@ -21,4 +23,17 @@
Error = error; Error = error;
} }
} }
public class WebCallResult<T>: CallResult<T>
{
/// <summary>
/// The status code of the response. Note that a OK status does not always indicate success, check the Success parameter for this.
/// </summary>
public HttpStatusCode? ResponseStatusCode { get; set; }
public WebCallResult(HttpStatusCode? code, T data, Error error): base(data, error)
{
ResponseStatusCode = code;
}
}
} }

View File

@ -67,7 +67,7 @@ namespace CryptoExchange.Net.Requests
public async Task<IResponse> GetResponse() public async Task<IResponse> GetResponse()
{ {
return new Response(await request.GetResponseAsync().ConfigureAwait(false)); return new Response((HttpWebResponse)await request.GetResponseAsync().ConfigureAwait(false));
} }
} }
} }

View File

@ -6,9 +6,11 @@ namespace CryptoExchange.Net.Requests
{ {
public class Response : IResponse public class Response : IResponse
{ {
private readonly WebResponse response; private readonly HttpWebResponse response;
public Response(WebResponse response) public HttpStatusCode StatusCode => response.StatusCode;
public Response(HttpWebResponse response)
{ {
this.response = response; this.response = response;
} }

View File

@ -115,13 +115,13 @@ namespace CryptoExchange.Net
/// <param name="signed">Whether or not the request should be authenticated</param> /// <param name="signed">Whether or not the request should be authenticated</param>
/// <param name="checkResult">Whether or not the resulting object should be checked for missing properties in the mapping (only outputs if log verbosity is Debug)</param> /// <param name="checkResult">Whether or not the resulting object should be checked for missing properties in the mapping (only outputs if log verbosity is Debug)</param>
/// <returns></returns> /// <returns></returns>
protected virtual async Task<CallResult<T>> ExecuteRequest<T>(Uri uri, string method = Constants.GetMethod, Dictionary<string, object> parameters = null, bool signed = false, bool checkResult = true) where T : class protected virtual async Task<WebCallResult<T>> ExecuteRequest<T>(Uri uri, string method = Constants.GetMethod, Dictionary<string, object> parameters = null, bool signed = false, bool checkResult = true) where T : class
{ {
log.Write(LogVerbosity.Debug, "Creating request for " + uri); log.Write(LogVerbosity.Debug, "Creating request for " + uri);
if (signed && authProvider == null) if (signed && authProvider == null)
{ {
log.Write(LogVerbosity.Warning, $"Request {uri.AbsolutePath} failed because no ApiCredentials were provided"); log.Write(LogVerbosity.Warning, $"Request {uri.AbsolutePath} failed because no ApiCredentials were provided");
return new CallResult<T>(null, new NoApiCredentialsError()); return new WebCallResult<T>(null, null, new NoApiCredentialsError());
} }
var request = ConstructRequest(uri, method, parameters, signed); var request = ConstructRequest(uri, method, parameters, signed);
@ -138,7 +138,7 @@ namespace CryptoExchange.Net
if (!limitResult.Success) if (!limitResult.Success)
{ {
log.Write(LogVerbosity.Debug, $"Request {uri.AbsolutePath} failed because of rate limit"); log.Write(LogVerbosity.Debug, $"Request {uri.AbsolutePath} failed because of rate limit");
return new CallResult<T>(null, limitResult.Error); return new WebCallResult<T>(null, null, limitResult.Error);
} }
if (limitResult.Data > 0) if (limitResult.Data > 0)
@ -152,16 +152,20 @@ namespace CryptoExchange.Net
log.Write(LogVerbosity.Debug, $"Sending {method}{(signed ? " signed" : "")} request to {request.Uri} {paramString ?? ""}"); log.Write(LogVerbosity.Debug, $"Sending {method}{(signed ? " signed" : "")} request to {request.Uri} {paramString ?? ""}");
var result = await ExecuteRequest(request).ConfigureAwait(false); var result = await ExecuteRequest(request).ConfigureAwait(false);
if(!result.Success) if(!result.Success)
return new CallResult<T>(null, result.Error); return new WebCallResult<T>(result.ResponseStatusCode, null, result.Error);
var jsonResult = ValidateJson(result.Data); var jsonResult = ValidateJson(result.Data);
if(!jsonResult.Success) if(!jsonResult.Success)
return new CallResult<T>(null, jsonResult.Error); return new WebCallResult<T>(result.ResponseStatusCode, null, jsonResult.Error);
if (IsErrorResponse(jsonResult.Data)) if (IsErrorResponse(jsonResult.Data))
return new CallResult<T>(null, ParseErrorResponse(jsonResult.Data)); return new WebCallResult<T>(result.ResponseStatusCode, null, ParseErrorResponse(jsonResult.Data));
return Deserialize<T>(jsonResult.Data, checkResult); var desResult = Deserialize<T>(jsonResult.Data, checkResult);
if (!desResult.Success)
return new WebCallResult<T>(result.ResponseStatusCode, null, desResult.Error);
return new WebCallResult<T>(result.ResponseStatusCode, desResult.Data, null);
} }
/// <summary> /// <summary>
@ -258,7 +262,7 @@ namespace CryptoExchange.Net
/// </summary> /// </summary>
/// <param name="request">The request object to execute</param> /// <param name="request">The request object to execute</param>
/// <returns></returns> /// <returns></returns>
private async Task<CallResult<string>> ExecuteRequest(IRequest request) private async Task<WebCallResult<string>> ExecuteRequest(IRequest request)
{ {
var returnedData = ""; var returnedData = "";
try try
@ -272,12 +276,15 @@ namespace CryptoExchange.Net
log.Write(LogVerbosity.Debug, "Data returned: " + returnedData); log.Write(LogVerbosity.Debug, "Data returned: " + returnedData);
} }
var statusCode = response.StatusCode;
response.Close(); response.Close();
return new CallResult<string>(returnedData, null); return new WebCallResult<string>(statusCode, returnedData, null);
} }
catch (WebException we) catch (WebException we)
{ {
var response = (HttpWebResponse)we.Response; var response = (HttpWebResponse)we.Response;
var statusCode = response?.StatusCode;
try try
{ {
using (var reader = new StreamReader(response.GetResponseStream())) using (var reader = new StreamReader(response.GetResponseStream()))
@ -289,7 +296,7 @@ namespace CryptoExchange.Net
response.Close(); response.Close();
var jsonResult = ValidateJson(returnedData); var jsonResult = ValidateJson(returnedData);
return !jsonResult.Success ? new CallResult<string>(null, jsonResult.Error) : new CallResult<string>(null, ParseErrorResponse(jsonResult.Data)); return !jsonResult.Success ? new WebCallResult<string>(statusCode, null, jsonResult.Error) : new WebCallResult<string>(statusCode, null, ParseErrorResponse(jsonResult.Data));
} }
catch (Exception) catch (Exception)
{ {
@ -300,18 +307,18 @@ namespace CryptoExchange.Net
{ {
infoMessage += $" | {we.Status} - {we.Message}"; infoMessage += $" | {we.Status} - {we.Message}";
log.Write(LogVerbosity.Warning, infoMessage); log.Write(LogVerbosity.Warning, infoMessage);
return new CallResult<string>(null, new WebError(infoMessage)); return new WebCallResult<string>(0, null, new WebError(infoMessage));
} }
infoMessage = $"Status: {response.StatusCode}-{response.StatusDescription}, Message: {we.Message}"; infoMessage = $"Status: {response.StatusCode}-{response.StatusDescription}, Message: {we.Message}";
log.Write(LogVerbosity.Warning, infoMessage); log.Write(LogVerbosity.Warning, infoMessage);
response.Close(); response.Close();
return new CallResult<string>(null, new ServerError(infoMessage)); return new WebCallResult<string>(statusCode, null, new ServerError(infoMessage));
} }
catch (Exception e) catch (Exception e)
{ {
log.Write(LogVerbosity.Error, $"Unknown error occured: {e.GetType()}, {e.Message}, {e.StackTrace}"); log.Write(LogVerbosity.Error, $"Unknown error occured: {e.GetType()}, {e.Message}, {e.StackTrace}");
return new CallResult<string>(null, new UnknownError(e.Message + ", data: " + returnedData)); return new WebCallResult<string>(null, null, new UnknownError(e.Message + ", data: " + returnedData));
} }
} }