The TryThis method

The more I learn and use dynamic languages like JavaScript and Ruby, the more I feel the constraints placed on me by the C# compiler.  Today I needed to wrap a bunch of calls to a web service facade in some try catch statements.  I really hated the idea of littering my code with these because a lot them make the code that much harder to read.  What I really wanted was a method that would execute the statement in a try/catch and do the necessary exception handling for me. In this situation, the method calls were very different (number of parameters, return values), but the error handling was exactly the same.

What I really wanted was something like the block statement in Ruby, where I just pass in arbitrary code to a method that would then execute it.  It was a little trickier in C# because of the variations in the method signture.  A method that had a Func parameter wouldn’t work because I had varying number of parameters.  Also the changing return value added a nice twist.  In the end, it came out rather nice.

With this little method I can now pass in any method and

private bool TryThis(Action block)
        {
            
try
            {
                block();
                
return true;
            }
            
catch(Exception)
            {
                
//do something with exception here
                return false;
            }
        

Here are a few tests to show what it looks like.

public interface Foo
    {
        
DateTime Bar(string a, string b);
        
string Bar2(int a);
        
void Bar3(int a, int b);
    }
    [
TestFixture]
    
public class trythis_specs
    {
        
private Foo mock;

        [SetUp]
        
public void setup()
        {
            mock =
MockRepository.GenerateMock<Foo>();
        }
       [
Test]
      
public void should_return_true_when_there_is_no_exception()
       {
           mock.Stub(m => m.Bar(
“a”, “b”)).Return(DateTime.Now);
          
DateTime output;
          
bool result = TryThis(() => output = mock.Bar(“a”, “b”));
          
Assert.That(result);

       }
       [Test]
        
public void can_get_the_value_from_executing_method()
       {
          
var time = DateTime.Now;
           mock.Stub(m => m.Bar(
“a”, “b”)).Return(time);
          
DateTime output = DateTime.MinValue;
          
bool result = TryThis(() => output = mock.Bar(“a”, “b”));
          
Assert.That(output, Is.EqualTo(time));
       }
       [
Test]
        
public void return_false_on_exception()
        {
           mock.Stub(m => m.Bar3(1,2)).Throw(
new Exception());
          
var result = TryThis(() => mock.Bar3(1,2));
          
Assert.That(result, Is.False);
        

That’s not quite as clean a block parameter in Ruby, but I can live with it for now.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

This entry was posted in c#. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Michael Hart

    It’s that nice little “do something with exception here” that’s gonna trip you up – especially if you’re trying to make it a generic piece of code.

    Just make sure you don’t swallow it unless you really really mean to.

  • http://www.timvw.be Tim Van Wassenhove

    In most use-cases i would want to have more control about the type of exceptions that are swallowed… Probably something like:

    private bool TryThis(Action block, Func exceptionHandler)
    {
    try
    {
    block();
    return true;
    }
    catch(Exception ex)
    {
    if(!exceptionHandler(ex)) throw;
    return false;
    }
    }

  • Nick

    This seems like a good solution to check that *an* exception has been thrown. The only problem is that if you want to be testing your exceptional cases to see what type of exception it was or what the message was, you can’t do it with this.

  • http://tunatoksoz.com Tuna Toksoz

    My favorite is:

    Try.Something(()=>doexceptionalthinghere())
    .Catch(x=>dosomethingwithx)

    i don’t use this at all, but like it anyway :)

  • pablo

    My tests are always located in a separated project that contains ONLY the NUnit test classes.

    The problem that I’m facing with it is that I cannot test protected/private methods.

    How would you test your protected/private methods?

  • David Thibault

    Nice idea. Also :

    public static class Try {
    public static bool This< T >(Func< T > block, out T result) {
    try {
    result = block();
    return true;
    }
    catch (Exception) {
    result = default(T);
    return true;
    }
    }
    }

    And then :

    int result;
    if (Try.This(() => MightGoWrong(), out result)) {
    // it worked and we have the result :)
    }

  • http://Http://lazycoder.com Scott Koon

    We use a similar method called WrapWithStandardExceptionHandling in our service layer, but we use it in a lambda. I can’t remember the specific implementation details right now though, it’s 5 AM here, I’ll look at it at work and see if it might have the same effect.

  • http://www.lostechies.com/members/jcteague/default.aspx jcteague

    @Micheal, @Nick
    I don’t use production code in my blog posts. I’m trying to illustrate how you can use delegates to clean up you code. In reality I am catching a specific exception. As some of the other commenters have mentioned, if you want something more generic there are ways.

    @David, I started with a Func paramter, but because of the different number of input paramters didn’t work very well. That’s why I encapsulated it in a action where I can handle any number of paramters, different output parameters easily.

    @Tuna, I like that. I thought about doing something a little more fluentish. Maybe next time.

  • http://www.lostechies.com/members/jcteague/default.aspx jcteague

    @pablo
    I don’t test private methods directly, I just put the method in my test class for the purpose of this demonstration.

    Usually I’ll will test the public methods that call the private method and make sure I get all of the paths with NCover.

    You can test protected methods by creating a test double. I’ll do a post about that tonight.

  • http://journalofasoftwaredev.wordpress.com/ Mike

    For this cross-cutting code I tend to use AOP using Castle Windsor for instance by convention all public methods on my controllers will have an interceptor assigned to them to handle logging of any unhandled exceptions http://code.google.com/p/issuetrackerdotnet/source/browse/trunk/src/IssueTracker.Controllers/ExceptionLoggingInterceptor.cs

    This way your code does not need to change at all no lamdas needed!

  • http://lazycoder.com Scott Koon

    Yeah, we do something like this:

    protected T WrapWithStandardExceptionHandling(int eventLogId, Func func)
    {
    try
    {
    var result = func();
    return result;
    }
    catch (Exception e)
    {
    if (!(typeof(BaseException).IsAssignableFrom(e.GetType())))
    {
    Log.Instance.LogError(eventLogId, e);
    }
    throw;
    }
    }