0

In my code I have many functions with this signature (params + return type), and they all use this same try-catch clause.

public ActionResult methodName(int id)
{
    try
    {
        //Some specific code here
        return new HttpStatusCodeResult(HttpStatusCode.OK);
    }
    catch (Exception ex)
    {
        return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, ex.Message);
    }
}

Now, This is replicated over and over again, and I know that replication is bad. The reason this happens, is because I want the code to be able to return multiple HttpStatusCodeResult but I don't know a better way of doing it.

In this example, I return an internal server error and an OK answer. But what if I want to return another type of error ?

public ActionResult methodName(int id)
{
    try
    {
        //Some specific code here
        if(conditionA)
            return return new HttpStatusCodeResult(HttpStatusCode.NotFound, "No Hamsters found!")
        return new HttpStatusCodeResult(HttpStatusCode.OK);
    }
    catch (Exception ex)
    {
        return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, ex.Message);
    }
}

Is there a modular way of having behavior, without replication, inside my code? Is there a design or architectural pattern I can use? If so, which one?

Loofer
  • 6,841
  • 9
  • 61
  • 102
Flame_Phoenix
  • 16,489
  • 37
  • 131
  • 266
  • Instead of `try..catch`, use an exception filter. – CodeCaster Mar 03 '15 at 10:34
  • Can you give an example? I have no idea what you are talking about :S – Flame_Phoenix Mar 03 '15 at 10:36
  • [Filtering in ASP.NET MVC](https://msdn.microsoft.com/en-us/library/gg416513%28VS.98%29.aspx) – CodeCaster Mar 03 '15 at 10:41
  • The replication is connected to creating exceptions, not dealing with them. Filters wont do :S – Flame_Phoenix Mar 03 '15 at 10:43
  • You can remove the `try..catch` blocks and use a filter to `return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, ex.Message);` in case of an exception instead. Then you're left with `if (condA) { return new (...) } else { return new (...) }`. If you even don't want that, you can set the status code and text in a variable and `return new HttpStatusCodeResult(statusCode, statusText)` ... repeating that in every action method. – CodeCaster Mar 03 '15 at 10:46

1 Answers1

7

You can factorize a little like this :

public static class Helper
{
    public static ActionResult TryCatch(Func<ActionResult> funk)
    {
        try
        {
            if (funk != null)
            {
                ActionResult result = funk();
                if (result != null)
                    return result;
            }
        }
        catch (Exception ex)
        {
            return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, ex.Message);
        }
        return new HttpStatusCodeResult(HttpStatusCode.OK);
    }
}

And call it like this :

public ActionResult methodName(int id)
{
    return Helper.TryCatch(() => 
       {
            //Some specific code here
            if(conditionA)
                return return new HttpStatusCodeResult(HttpStatusCode.NotFound, "No Hamsters found!")
            return null;
       };
}        
rducom
  • 7,072
  • 1
  • 25
  • 39
  • do I really need the return null at the end? Other than that it looks like a cool solution to me. Is this using patterns or anything? – Flame_Phoenix Mar 03 '15 at 14:59
  • 1
    It's a Func, so you have to return something (a Func is like a method returning T, so if you don't return something, you have compilation errors). It's not a design pattern, or if it's something, it's an implementation of the DRY principle :) http://en.wikipedia.org/wiki/Don%27t_repeat_yourself – rducom Mar 03 '15 at 15:04