I have a c# library that sends requests to a number of HTTP endpoints and then tries to de-serialize the result into the specified type. An indicative method is defined as:
public virtual async Task<(T, HttpStatusCode)> GetAsync<T>(string resource)
The issue I now have is that I would like to return more contextual information if there is an error response from the endpoint, in the form of an ErrorResponse
object. Refactoring the code base to allow for that to occur would be a substantial change if I were to just update the method signature to return ErrorResponse
as an addition to the returned tuple because c# doesn't allow for methods to be differentiated by return type, e.g.
public virtual async Task<(T, HttpStatusCode, ErrorResponse)> GetAsync<T>(string resource)
Similarly if I introduced OneOf I would still be modifying the return type of the method, not the parameters:
public virtual async Task<(OneOf<T, ErrorResponse>, HttpStatusCode)> GetAsync<T>(string resource)
Clearly returning some kind of response object containing the HttpStatusCode, T
, and any error information would have been more flexible. 20-20 hindsight is a wonderful thing but unfortunately doesn't provide a simple way forward.
public virtual async Task<Response<T>> GetAsync<T>(string resource)
It's possible I could define parallel methods that don't modify the existing methods but provide the additional information.
public virtual async Task<Response<T>> Getv2Async<T>(string resource)
What is a useful/recommended approach to addressing this situation?
HttpStatusCode
and theErrorResponse
information into an exception? I guess then I would need to refactor the existing code to handle the new exception whereas currently there is some decision logic around the HttpStatusCode. At least if I introduced a new version of the API then I know exactly where the new version is called because it would only be a handful of requests initially.OneOf
.