C
C#ā€¢10mo ago
LazyGuard

āœ… Functional programming instead of exceptions

I've watched this video where Derek implements an Either from scratch to make method signatures more explicit rather than throwing an exception. He also adds a Map method to force the client code to deal with both cases However, the problem is that not every method has one successful path and one failure path. For example, the PostAsync. has many possible ways to fail (see exceptions here https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.postasync?view=net-8.0 ). So how to deal with this kind of situations ? especially if we want to keep the granularity of all the different ways to fail and we want to handle different failures in different ways in the client code
HttpClient.PostAsync Method (System.Net.Http)
Send a POST request to the specified Uri as an asynchronous operation.
19 Replies
Jimmacle
Jimmacleā€¢10mo ago
using a more generalized union type like OneOf
LazyGuard
LazyGuardOPā€¢10mo ago
it seems like an overkill for me :/
Jimmacle
Jimmacleā€¢10mo ago
seems like exactly what you asked for, but i don't know your application Either is basically a OneOf that's limited to exactly 2 options
LazyGuard
LazyGuardOPā€¢10mo ago
I am thinking about defining some abstract class Error and then have Error 1 and Error2 inherit from that abstract class. In the client code I will use the Either , the signature will look something like Either<Order,Error> then when I do the pattern matching using the Map it will look like

result.Match<IActionResult>(
order => PlaceOrder(),
error => { //checking depending on the type of error};
}

result.Match<IActionResult>(
order => PlaceOrder(),
error => { //checking depending on the type of error};
}
Jimmacle
Jimmacleā€¢10mo ago
if you don't want to force the caller to handle all possible errors, sure
LazyGuard
LazyGuardOPā€¢10mo ago
you mean the forcing in Either is done by the use of Map . However the pattern-matching depending on the type of the error is the built-in C# pattern matching which is not exhaustive, right ?
Pobiega
Pobiegaā€¢10mo ago
If you use OneOf, each possible error type is explicit - which leads to really long type signatures, but hey, you get exhaustive error handling if you go for the Error base class type thing instead, you do unfortunately lose that exhaustiveness its a tradeoff
LazyGuard
LazyGuardOPā€¢10mo ago
right, but the OnfeOff could result in a huge signature also, OneOff will put the errors as well as the sucess in the same bag maybe sometime I would like to treat the ok path and the NotOk path with every possible error, so if there is 1 ok and n error, I will need n+1 execution paths but other times I would only like to have only two execution paths: 1 for the ok case and one for all of the NotOk case Do you see what I mean ?
Pobiega
Pobiegaā€¢10mo ago
You can't have your cake and eat it too.
LazyGuard
LazyGuardOPā€¢10mo ago
I dont like my code to look like result.Match<IActionResult>( order => PlaceOrder(), error1 => handleError() error2 => handleError() error3 => handleError() } It's repition
Pobiega
Pobiegaā€¢10mo ago
sure So don't do that, if thats not what you want :p
LazyGuard
LazyGuardOPā€¢10mo ago
I am wondering if there is some soultion šŸ˜…
Pobiega
Pobiegaā€¢10mo ago
No golden bullet, no either you want forced exhaustive matching, and then you go with OneOf or you don't, and use an Either or literally any of the already made libs for it $resultlibs
MODiX
MODiXā€¢10mo ago
Tag Search Results
Tags matching the search query "result": ā€¢ getawaitergetresult ā€¢ getresult ā€¢ result ā€¢ resultlib
4 of 4 results shown
Pobiega
Pobiegaā€¢10mo ago
$resultlib
LazyGuard
LazyGuardOPā€¢10mo ago
Well, I will go with the Either. Thus, this would force the client code to handle both happy and unhappy path. Then, if there is multiple possible unhappy paths I would go with Error base class and leave out the responsability to decide the exhaustiveness and grouping etc on the client code
Pobiega
Pobiegaā€¢10mo ago
yeah thats kinda what I do I usually go with Remora.Results, which is a simple Result<TSuccess,TError> so in the case of multiple possible errors, there is an IError
LazyGuard
LazyGuardOPā€¢10mo ago
I Will check this out Thank you !
Want results from more Discord servers?
Add your server