I have the following C# code (.NET 6):
public async Task<IEnumerable<Foobar>> RetrieveFoobar(string accessToken, CancellationToken cancellationToken)
{
try
{
using var httpClient = new HttpClient(new HttpClientHandler())
{
BaseAddress = new Uri(_baseUrl)
};
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await httpClient.GetAsync("/path", cancellationToken);
if (!response.IsSuccessStatusCode)
{
Log.Error($"Foobar failed: {response.StatusCode} - {await response.Content.ReadAsStringAsync(cancellationToken)}");
return null;
}
var results = await JsonSerializer.DeserializeAsync<FooBarWrapper>(await response.Content.ReadAsStreamAsync(cancellationToken), cancellationToken: cancellationToken);
if (results == null)
{
Log.Error("Json deserialisation failed when parsing Foobar results");
return null;
}
if (!results.Success)
{
Log.Error("Foobar response was marked as unsuccessful.");
return null;
}
return results.Records;
}
catch (Exception e)
{
Log.Error(e, "Foobar retrieval failed");
return null;
}
}
It's a fairly simple function that retrieves some results from a REST call.
The problem is, only around 8 of these 40 lines of code provide the core functionality, the rest is essentially error handling. Most of the code is like this, when reading through it I have to wade through blocks of error handling.
I'm writing this code in a service in which reliability and robustness are extremely important.
Is this normal? Or am I going overboard? Is this a good thing? Should readability be sacrificed in the name of robustness? Is there a better way of doing this?