I am developing a long pipeline of data flow consisting of several blocks. Elements are fed into the input block of the conveyor, finally made their way through it and displayed in the user interface at the end (as a courtesy for the user, the real task of the conveyor is to save the processing results to disk).
Lambda functions inside pipeline blocks can throw exceptions for various reasons (poor input, network failure, error during calculation, whatever). In this case, instead of abandoning the entire pipeline, I would like to release an offensive element and display it in the user interface in the "Errors" section.
What is the best way to do this? I understand that I can wrap every lambda function in try / catch:
var errorLoggingBlock = new ActionBlock<Tuple<WorkItem, Exception>>(...) var workerBlock = new TransformBlock<WorkItem, WorkItem>(item => { try { return DoStuff(item); } catch (Exception ex) { errorLoggingBlock.SendAsync(Tuple.Create(item, ex)); return null; } }
But I have about 10 blocks in the pipeline, and copying / pasting this code into each of them seems silly. In addition, I do not like the idea of ββreturning null, since now all subordinate blocks will have to check it.
My next best idea is to create a function that returns a lambda that does the wrapper for me:
private Func<TArg, TResult> HandleErrors<TArg, TResult>(Func<TArg, TResult> f) where TArg:WorkItem { return arg => { try { return f(arg); } catch (Exception ex) { errorLoggingBlock.SendAsync(Tuple.Create(item, ex)); return default(TResult); } }; }
But that seems too meta. Is there a better way?
c # error-handling tpl-dataflow
Bugmaster
source share