using Sports.Services.Network;
using PlainHttp;
using HttpRequest = PlainHttp.HttpRequest;
namespace Proj
{
public class HttpBase
{
public static IHttpRequest ProxiedRequest(string url)
{
IHttpRequest request = new HttpRequest(url)
{
Proxy = new Uri(Proxies.getRandomProxyConnection()),
Timeout = TimeSpan.FromMilliseconds(5000)
};
return request;
}
}
}
One of many inherited classes -
public class HttpSiteA : HttpBase
{
public static async Task<IHttpResponse> Get(string url)
{
IHttpRequest request = ProxiedRequest(url);
return await request.SendAsync();
}
}
Then later on..
public static async Task<int> ProcessSchedule(SportLeagueStruct league, ILogger logger)
{
IHttpResponse response = await HttpSiteA.Get(string.Format(scheduleUrl, league.fanduelName));
if (response.Succeeded)
{
JObject obj = JObject.Parse(response.Body);
if (obj?["attachments"]?["events"].Count() > 1)
{
logger.LogWarning("FAILURE");
}
return 0;
}
return 1;
}
var tasks = new List<Task>();
tasks.Add(SiteA.ProcessSchedule(SportLeagues.MLB, logger));
tasks.Add(SiteB.ProcessSchedule(SportLeagues.MLB, logger));
tasks.Add(SiteC.ProcessSchedule(SportLeagues.MLB, logger));
tasks.Add(SiteD.ProcessSchedule(SportLeagues.MLB, logger));
tasks.Add(SiteE.ProcessSchedule(SportLeagues.MLB, logger));
try
{
await Task.WhenAll(tasks);
}
catch { }
I have the above function ProxiedRequest
. If my request
timesout, it throws a timeout exception. However, If my request timesout, instead of timing out, I would like to return a mocked IHttpRequest
where everything is empty but has a status code of 401. I would simply put a try/catch
around the IHttpRequest request = new HttpRequest(url)..
and in the catch, return the mocked request. However, I have not been able to figure out how to create a mocked request. Could anyone help me with that?
The idea is I don't want to have to try/catch a timeout exception later in my code and would rather just process the request as a non-200 status code as the handling when processing the request would be the same and I don't need to deal with an exception.
CodePudding user response:
The question is just wrong, exception is thrown not by request
object, but by SendAsync()
method. See their snippet from github.
try
{
IHttpResponse response = await request.SendAsync();
}
catch (HttpRequestException ex)
{
if (ex is HttpRequestTimeoutException)
{
Console.WriteLine("Request timed out");
}
else
{
Console.WriteLine("Something bad happened: {0}", ex);
// PlainHttp.HttpRequestException: Failed request: [GET https://yyyy.org/] [No such host is known] ---> System.Net.Http.HttpRequestException: No such host is known ---> System.Net.Sockets.SocketException: No such host is known
// etc.
}
}
You need to refactor your base class, move your Get
method there and include error handling logic if you don't want to handle errors in each implementation.
public class HttpBase
{
public IHttpRequest ProxiedRequest(string url)
{
var request = new HttpRequest(url)
{
Proxy = new Uri(""),
Timeout = TimeSpan.FromMilliseconds(5000)
};
return request;
}
public virtual async Task<IHttpResponse> Get(string url)
{
IHttpRequest request = ProxiedRequest(url);
try
{
return await request.SendAsync();
}
catch
{
HttpResponseMessage httpResponseMessage = new HttpResponseMessage()
{
StatusCode = (HttpStatusCode)401,
Content = new StringContent("")
};
IHttpResponse mockResponse = new HttpResponse(request as HttpRequest, httpResponseMessage);
return mockResponse;
}
}
}
public class HttpSiteA : HttpBase
{
// override its implementation if it differs from the base
}