vkhorikov / CSharpFunctionalExtensions

Functional extensions for C#

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] Adding shared context for Result which presents in both Success and Error cases

hankovich opened this issue · comments

I'm writing an important integration with a buggy third-party API that constantly changes its returning models. For debugging purposes and to be able to reprocess or replay its responses, I want to store plain responses along with some metadata like request duration. So, I'm looking for something like:

async Task<Result<Response, Error>> InvokeAsync()
{
    var firstResponse = await GetResponseAsStringAsync(...); // network call that returns raw API response, may fail
    var parsedFirstResponse = serializer.Deserialize<FirstResponse>(firstResponse); // may fail because API has weird contracts
    
    var secondResponse = await httpClient.GetStringAsync/* some parts of parsedFirstResponse */); // may fail
    var parsedSecondResponse = serializer.Deserialize<SecondResponse>(secondResponse); // may fail
}

And I want the Result I return to have some shared context in both success and error cases. In the case of success, it will have information about two successful responses, including their raw values and durations. In the case of failure, it will contain all available information (i.e., if processing fails during parsing, I want the Result to contain the raw response that caused parsing issues).

Has anyone ever faced such requirements before? I'm considering adding Result<T, TError, TContext> to my project.

Sorry for late replies here.

This looks similar to the state monad (or maybe not, it's been awhile since I read that article). I would introduce a custom class to handle the intermediate result of the parsing and only use Result<T, E> at the edges of the parsing function. There's just too much going on during parsing and trying to cram all that into the "standard" Result won't do any good.