A Waterfall pattern for C#

First, let’s paint a scenario – you can query multiple sources for the same data, with the hope that one of these sources will have a response.
These sources can respond in three possible ways;
1 . An answer.
2. An exception indicating that the answer is impossible, and there is no need to query other sources
3. An exception indicating that the source failed, but perhaps another source will work.
So, Let’s define an exception of case (2)
class ExpectedException : Exception
{
}
Now, define our three sources, which must have the same input and output types, in this case they will be strings, but they could be any types, as long as they are consistent.
static string SourceA(string input)
{
throw new Exception("Some random error");
}
static string SourceB(string input)
{
throw new ExpectedException();
}
static string SourceC(string input)
{
return "OK";
}
Now, we define a Waterfall function, that will call a list of functions in order, until it reaches either case (1) or case (2)
private static T1 Waterfall<T1,T2>(IEnumerable<Func<T2, T1>> waterfallFunctions, T2 parameter)
{
var waterfallExceptions = new List<Exception>();
foreach (var waterfallFunction in waterfallFunctions)
{
try
{
var functionResult = waterfallFunction(parameter);
return functionResult;
}
catch (ExpectedException)
{
throw;
}
catch (Exception e)
{
waterfallExceptions.Add(e);
}
}
throw new AggregateException(waterfallExceptions);
}
Which is called as follows
var result = Waterfall( new List<Func<string, string>>
{
SourceA,
SourceC,
SourceB
},"hello");
This code is available on a public Github repo here: https://github.com/infiniteloopltd/Waterfall
Hope this helps someone!