Search code examples
c#lambdacode-reuse

Using a message class static method taking in an action to wrap Try/Catch


I have a Result object that lets me pass around a List of event messages and I can check whether an action was successful or not.

I've realized I've written this code in alot of places

Result result;

try
{
    //Do Something 
    ...

    //New result is automatically a success for not having any errors in it
    result = new Result(); 
}
catch (Exception exception)
{
    //Extension method that returns a Result from the exception
    result = exception.ToResult();
}

if(result.Success) ....

What I'm considering is replacing this usage with

public static Result CatchException(Action action)
{
    try
    {
        action();
        return new Result();
    }
    catch (Exception exception)
    {
        return exception.ToResult();
    }
}

And then use it like

var result = Result.CatchException(() => _model.Save(something));

Does anyone feel there's anything wrong with this or that I'm trading reusability for obscurity?

Edit: The reason I am trapping all exceptions is I use this code inside of my ViewPresenter classes at any point I interact with my model since if I get an unhandled exception I'd rather display the actual error to the user (internal app) as opposed to just redirecting them the generic error page.


Solution

  • I don't think there is anything wrong with using a functional approach, and passing in a lambda. That is perfectly valid.

    That being said, I'd question your use in this specific scenario. Trapping all exceptions into a general purpose "Result" class seems dangerous. Ideally, you should be catching exceptions which you can handle correctly - not every possible exception and continuing.

    That being said, if you really want to do this, I have a couple of suggestions for you:

    1) I'd make a static, immutable result for success, and just do:

    result = result.Success;
    

    This avoids generating a new "success" each time you succeed, which hopefully is the most common option.

    2) I'd probably avoid the extension method, and do:

    result = new Result(exception);
    

    This will be much more clear and obvious in intent, and there's really no reason to do an extension method in this case...