Refactoring tips and tricks: Exceptions

Consider the following class:

    public class FooService
    {
        private readonly ILogger _logger;

        public FooService(ILogger logger)
        {
            _logger = logger;
        }

        public void Foo()
        {
            try
            {
                // Foo code goes here...
            }
            catch (Exception ex)
            {
                _logger.LogException(ex);
            }
        }

        public void Bar()
        {
            try
            {
                // Bar code goes here...
            }
            catch (Exception ex)
            {
                _logger.LogException(ex);
            }
        }
    }
    

This is a very common scenario that I’ve seen in many different places over the last few years – each method has some code wrapped in a try-catch block. To get rid of the code duplication is easy, we can move the try-catch block to a new method that will take a delegate as a parameter (code to be executed):

    private void Try(Action action)
    {
        try
        {
            action();
        }
        catch (Exception ex)
        {
            _logger.LogException(ex);
        }
    }

Refactoring the class:

    public class FooService
    {
        private readonly ILogger _logger;

        public FooService2(ILogger logger)
        {
            _logger = logger;
        }

        public void Foo()
        {
            Try(() => {
                // Foo code goes here...
            });
        }

        public void Bar()
        {
            Try(() => {
                // Bar code goes here...
            });
        }

        private void Try(Action action)
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                _logger.LogException(ex);
            }
        }
    }